From 8c092dc680c87877f6f782c9d21f06c57557e38e Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 12 Mar 2024 09:26:49 -0400 Subject: [PATCH 01/61] Fixes command line multisig join for incept/rotate/interact (#707) * updates intcept/interact/rotate to use clone exn Signed-off-by: Kevin Griffin * wip Signed-off-by: Kevin Griffin * Update join incept flow to return the icp event to other members. Signed-off-by: pfeairheller * Updated new multisig join to use only the two members from this script for the rotation event and to include some data in the interaction event. Signed-off-by: pfeairheller * Add rotation of local AIDs before multisig rotate to new multisig join script. Signed-off-by: pfeairheller * updates to fix interact/roate Signed-off-by: Kevin Griffin * Fix multisig-join script so it can run alongside other scripts in CID. Signed-off-by: pfeairheller --------- Signed-off-by: Kevin Griffin Signed-off-by: pfeairheller Co-authored-by: pfeairheller --- keri/cf/demo-witness-oobis.json | 0 .../basic/keri/cf/demo-witness-oobis.json | 0 scripts/demo/basic/multisig-join.sh | 61 ++++ ...-join.sh => multisig-rotation-in-third.sh} | 0 scripts/demo/data/multisig-join-sample.json | 15 + scripts/demo/test_scripts.sh | 6 + src/keri/app/cli/commands/multisig/join.py | 298 ++++++++++++------ 7 files changed, 292 insertions(+), 88 deletions(-) create mode 100755 keri/cf/demo-witness-oobis.json create mode 100755 scripts/demo/basic/keri/cf/demo-witness-oobis.json create mode 100755 scripts/demo/basic/multisig-join.sh rename scripts/demo/basic/{multisig-rotation-join.sh => multisig-rotation-in-third.sh} (100%) create mode 100644 scripts/demo/data/multisig-join-sample.json diff --git a/keri/cf/demo-witness-oobis.json b/keri/cf/demo-witness-oobis.json new file mode 100755 index 000000000..e69de29bb diff --git a/scripts/demo/basic/keri/cf/demo-witness-oobis.json b/scripts/demo/basic/keri/cf/demo-witness-oobis.json new file mode 100755 index 000000000..e69de29bb diff --git a/scripts/demo/basic/multisig-join.sh b/scripts/demo/basic/multisig-join.sh new file mode 100755 index 000000000..dc32a4bb3 --- /dev/null +++ b/scripts/demo/basic/multisig-join.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# WITNESSES +# To run the following scripts, open another console window and run: +# $ kli witness demo + +kli init --name multisigj1 --salt 0ACDEyMzQ1Njc4OWxtbm9aBc --nopasscode --config-dir "${KERI_SCRIPT_DIR}" --config-file demo-witness-oobis +kli incept --name multisigj1 --alias multisigj1 --file ${KERI_DEMO_SCRIPT_DIR}/data/multisig-1-sample.json + +kli init --name multisigj2 --salt 0ACDEyMzQ1Njc4OWdoaWpsaw --nopasscode --config-dir "${KERI_SCRIPT_DIR}" --config-file demo-witness-oobis +kli incept --name multisigj2 --alias multisigj2 --file ${KERI_DEMO_SCRIPT_DIR}/data/multisig-2-sample.json + +kli oobi resolve --name multisigj1 --oobi-alias multisigj2 --oobi http://127.0.0.1:5642/oobi/EKJ6tNVUGbdaiwx2nWDCFXG-_PY_AzESOcoKlm0kRNP3/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha +kli oobi resolve --name multisigj2 --oobi-alias multisigj1 --oobi http://127.0.0.1:5642/oobi/EFY7MixHb0so4WFFHw6btOPc5qeeWfPm7v5MJWcdcbyG/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha + +PID_LIST="" + +kli multisig incept --name multisigj1 --alias multisigj1 --group multisig --file ${KERI_DEMO_SCRIPT_DIR}/data/multisig-join-sample.json & +pid=$! +PID_LIST+=" $pid" + +kli multisig join --name multisigj2 --auto & +pid=$! +PID_LIST+=" $pid" + +wait $PID_LIST + +kli status --name multisigj1 --alias multisig + +kli rotate --name multisigj1 --alias multisigj1 +kli query --name multisigj2 --alias multisigj2 --prefix EFY7MixHb0so4WFFHw6btOPc5qeeWfPm7v5MJWcdcbyG +kli rotate --name multisigj2 --alias multisigj2 +kli query --name multisigj1 --alias multisigj1 --prefix EKJ6tNVUGbdaiwx2nWDCFXG-_PY_AzESOcoKlm0kRNP3 + +PID_LIST="" + +kli multisig rotate --name multisigj1 --alias multisig --smids EKJ6tNVUGbdaiwx2nWDCFXG-_PY_AzESOcoKlm0kRNP3 --smids EFY7MixHb0so4WFFHw6btOPc5qeeWfPm7v5MJWcdcbyG --isith '["1/2", "1/2"]' --nsith '["1/2", "1/2"]' --rmids EKJ6tNVUGbdaiwx2nWDCFXG-_PY_AzESOcoKlm0kRNP3 --rmids EFY7MixHb0so4WFFHw6btOPc5qeeWfPm7v5MJWcdcbyG & +pid=$! +PID_LIST+=" $pid" + +kli multisig join --name multisigj2 --auto & +pid=$! +PID_LIST+=" $pid" + +wait $PID_LIST + +kli status --name multisigj1 --alias multisig + +PID_LIST="" + +kli multisig interact --name multisigj1 --alias multisig --data '{"d": "potato"}' & +pid=$! +PID_LIST+=" $pid" + +kli multisig join --name multisigj2 --auto & +pid=$! +PID_LIST+=" $pid" + +wait $PID_LIST + +kli status --name multisigj1 --alias multisig diff --git a/scripts/demo/basic/multisig-rotation-join.sh b/scripts/demo/basic/multisig-rotation-in-third.sh similarity index 100% rename from scripts/demo/basic/multisig-rotation-join.sh rename to scripts/demo/basic/multisig-rotation-in-third.sh diff --git a/scripts/demo/data/multisig-join-sample.json b/scripts/demo/data/multisig-join-sample.json new file mode 100644 index 000000000..1e9201cf4 --- /dev/null +++ b/scripts/demo/data/multisig-join-sample.json @@ -0,0 +1,15 @@ +{ + "aids": [ + "EKJ6tNVUGbdaiwx2nWDCFXG-_PY_AzESOcoKlm0kRNP3", + "EFY7MixHb0so4WFFHw6btOPc5qeeWfPm7v5MJWcdcbyG" + ], + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 2, + "isith": "2", + "nsith": "2" +} diff --git a/scripts/demo/test_scripts.sh b/scripts/demo/test_scripts.sh index 129723aab..7138d6bd8 100755 --- a/scripts/demo/test_scripts.sh +++ b/scripts/demo/test_scripts.sh @@ -63,3 +63,9 @@ printf "Running challenge.sh" printf "\n************************************\n" "${script_dir}/basic/challenge.sh" isSuccess + +printf "\n************************************\n" +printf "Running multisig-join.sh" +printf "\n************************************\n" +"${script_dir}/basic/multisig-join.sh" +isSuccess diff --git a/src/keri/app/cli/commands/multisig/join.py b/src/keri/app/cli/commands/multisig/join.py index e52dae7a1..e144c2c7b 100644 --- a/src/keri/app/cli/commands/multisig/join.py +++ b/src/keri/app/cli/commands/multisig/join.py @@ -6,6 +6,7 @@ """ import argparse import json +from ordered_set import OrderedSet as oset from hio.base import doing from prettytable import PrettyTable @@ -15,7 +16,6 @@ from keri.app.cli.common import existing, displaying from keri.core import coring, eventing, scheming, parsing, routing, serdering from keri.peer import exchanging -from keri.vc import proving from keri.vdr import verifying, credentialing logger = help.ogler.getLogger() @@ -27,6 +27,7 @@ required=False, default="") parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran +parser.add_argument("--auto", "-Y", help="auto approve any delegation request non-interactively", action="store_true") def confirm(args): @@ -39,8 +40,9 @@ def confirm(args): name = args.name base = args.base bran = args.bran + auto = args.auto - confirmDoer = ConfirmDoer(name=name, base=base, bran=bran) + confirmDoer = ConfirmDoer(name=name, base=base, bran=bran, auto=auto) doers = [confirmDoer] return doers @@ -51,7 +53,7 @@ class ConfirmDoer(doing.DoDoer): """ - def __init__(self, name, base, bran): + def __init__(self, name, base, bran, auto=False): """ Create doer for polling for group multisig events and either approve automatically or prompt user Parameters: @@ -87,7 +89,7 @@ def __init__(self, name, base, bran): doers = [self.hbyDoer, self.witq, self.mbx, self.counselor, self.registrar, self.credentialer, self.postman] self.toRemove = list(doers) doers.extend([doing.doify(self.confirmDo)]) - + self.auto = auto super(ConfirmDoer, self).__init__(doers=doers) def confirmDo(self, tymth, tock=0.0): @@ -106,50 +108,56 @@ def confirmDo(self, tymth, tock=0.0): print("Waiting for group multisig events...") - while True: - for keys, notice in self.notifier.noter.notes.getItemIter(): - attrs = notice.attrs - route = attrs['r'] - - match route: - case '/multisig/icp': - done = yield from self.incept(attrs) - case '/multisig/ixn': - done = yield from self.interact(attrs) - case '/multisig/rot': - done = yield from self.rotate(attrs) - case '/multisig/rpy': - done = yield from self.rpy(attrs) - case '/multisig/vcp': - done = yield from self.vcp(attrs) - case '/multisig/iss': - done = yield from self.iss(attrs) - case '/multisig/rev': - done = yield from self.rev(attrs) - case '/multisig/exn': - done = yield from self.exn(attrs) - case _: - continue - - if done: - self.notifier.noter.notes.rem(keys=keys) + while self.notifier.noter.notes.cntAll() == 0: + yield self.tock - else: - delete = input(f"\nDelete event [Y|n]? ") - if delete in ("Y", "y"): - self.notifier.noter.notes.rem(keys=keys) + for keys, notice in self.notifier.noter.notes.getItemIter(): + attrs = notice.attrs + route = attrs['r'] + + match route: + case '/multisig/icp': + done = yield from self.incept(attrs) + case '/multisig/ixn': + done = yield from self.interact(attrs) + case '/multisig/rot': + done = yield from self.rotate(attrs) + case '/multisig/rpy': + done = yield from self.rpy(attrs) + case '/multisig/vcp': + done = yield from self.vcp(attrs) + case '/multisig/iss': + done = yield from self.iss(attrs) + case '/multisig/rev': + done = yield from self.rev(attrs) + case '/multisig/exn': + done = yield from self.exn(attrs) + case _: + continue + + if done: + self.notifier.noter.notes.rem(keys=keys) + + else: + delete = input(f"\nDelete event [Y|n]? ") + if delete in ("Y", "y"): + self.notifier.noter.notes.rem(keys=keys) - yield self.tock yield self.tock + self.remove(self.toRemove) + def incept(self, attrs): """ Incept group multisig """ - smids = attrs["smids"] # change body mids for group member ids - rmids = attrs["rmids"] if "rmids" in attrs else None - ked = attrs["ked"] + said = attrs["d"] + exn, pathed = exchanging.cloneMessage(self.hby, said=said) + payload = exn.ked['a'] + smids = payload["smids"] + rmids = payload["rmids"] if "rmids" in payload else None + ked = exn.ked both = list(set(smids + (rmids or []))) mhab = None @@ -164,29 +172,40 @@ def incept(self, attrs): inits = dict() - inits["isith"] = ked["kt"] - inits["nsith"] = ked["nt"] + #original icp + embeds = exn.ked['e'] + oicp = serdering.SerderKERI(sad=embeds["icp"]) - inits["estOnly"] = eventing.TraitCodex.EstOnly in ked["c"] - inits["DnD"] = eventing.TraitCodex.DoNotDelegate in ked["c"] + inits["isith"] = oicp.ked["kt"] + inits["nsith"] = oicp.ked["nt"] - inits["toad"] = ked["bt"] - inits["wits"] = ked["b"] - inits["delpre"] = ked["di"] if "di" in ked else None + inits["estOnly"] = eventing.TraitCodex.EstOnly in oicp.ked["c"] + inits["DnD"] = eventing.TraitCodex.DoNotDelegate in oicp.ked["c"] + + inits["toad"] = oicp.ked["bt"] + inits["wits"] = oicp.ked["b"] + inits["delpre"] = oicp.ked["di"] if "di" in ked else None print() print("Group Multisig Inception proposed:") - self.showEvent(mhab, both, ked) - yn = input(f"\nJoin [Y|n]? ") - approve = yn in ('', 'y', 'Y') + self.showEvent(mhab, both, oicp.ked) + + if self.auto: + approve = True + else: + yn = input(f"\nJoin [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: - while True: - alias = input(f"\nEnter alias for new AID: ") - if self.hby.habByName(alias) is not None: - print(f"AID alias {alias} is already in use, please try again") - else: - break + if self.auto: + alias = "test alias" + else: + while True: + alias = input(f"\nEnter alias for new AID: ") + if self.hby.habByName(alias) is not None: + print(f"AID alias {alias} is already in use, please try again") + else: + break try: ghab = self.hby.makeGroupHab(group=alias, mhab=mhab, @@ -194,6 +213,28 @@ def incept(self, attrs): except ValueError as e: return False + icp = ghab.makeOwnInception(allowPartiallySigned=True) + + exn, ims = grouping.multisigInceptExn(ghab.mhab, + smids=ghab.smids, + rmids=ghab.rmids, + icp=icp) + others = list(oset(smids + (rmids or []))) + + others.remove(ghab.mhab.pre) + + for recpt in others: # this goes to other participants only as a signaling mechanism + self.postman.send(src=ghab.mhab.pre, + dest=recpt, + topic="multisig", + serder=exn, + attachment=ims) + + while not self.postman.sent(said=exn.said): + yield self.tock + + self.postman.cues.clear() + prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=0) saider = coring.Saider(qb64=prefixer.qb64) @@ -205,10 +246,18 @@ def incept(self, attrs): return True def interact(self, attrs): - pre = attrs["gid"] - smids = attrs["aids"] # change attrs["aids"]" to "smids" - rmids = attrs["rmids"] if "rmids" in attrs else None - data = attrs["data"] + said = attrs["d"] + exn, pathed = exchanging.cloneMessage(self.hby, said=said) + payload = exn.ked['a'] + + pre = payload["gid"] + smids = payload["smids"] + rmids = payload["rmids"] if "rmids" in payload else None + + embeds = exn.ked['e'] + # original ixn + oixn = serdering.SerderKERI(sad=embeds["ixn"]) + data = oixn.ked['a'] if pre not in self.hby.habs: print(f"Invalid multisig group interaction request {pre} not in Habs") @@ -225,12 +274,36 @@ def interact(self, attrs): print(f"Group Multisig Interaction for {ghab.name} ({ghab.pre}) proposed:") print(f"Data:") print(json.dumps(data, indent=2)) - yn = input(f"\nJoin [Y|n]? ") - approve = yn in ('', 'y', 'Y') + + if self.auto: + approve = True + else: + yn = input(f"\nJoin [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: ixn = ghab.interact(data=data) serder = serdering.SerderKERI(raw=ixn) + + ixn = ghab.makeOwnEvent(allowPartiallySigned=True, sn=oixn.sn) + + exn, ims = grouping.multisigInteractExn(ghab, aids=ghab.smids, ixn=ixn) + others = list(oset(smids + (rmids or []))) + + others.remove(ghab.mhab.pre) + + for recpt in others: # this goes to other participants only as a signaling mechanism + self.postman.send(src=ghab.mhab.pre, + dest=recpt, + topic="multisig", + serder=exn, + attachment=ims) + + while not self.postman.sent(said=exn.said): + yield self.tock + + self.postman.cues.clear() + prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=serder.sn) saider = coring.Saider(qb64b=serder.saidb) @@ -252,7 +325,6 @@ def startCounselor(self, hab, prefixer, seqner, saider): yield self.tock def showEvent(self, hab, mids, ked): - print() print("Participants:") thold = coring.Tholder(sith=ked["kt"]) @@ -284,9 +356,16 @@ def rotate(self, attrs): """ Rotate group multisig """ - smids = attrs["smids"] - rmids = attrs["rmids"] - ked = attrs["ked"] + said = attrs["d"] + exn, pathed = exchanging.cloneMessage(self.hby, said=said) + + payload = exn.ked['a'] + smids = payload["smids"] + rmids = payload["rmids"] + ked = exn.ked + + embeds = ked['e'] + orot = serdering.SerderKERI(sad=embeds["rot"]) both = list(set(smids + (rmids or []))) @@ -302,30 +381,58 @@ def rotate(self, attrs): print() print("Group Multisig Rotation proposed:") - self.showRotation(mhab, smids, rmids, ked) - yn = input(f"\nJoin [Y|n]? ") - approve = yn in ('', 'y', 'Y') + self.showRotation(mhab, smids, rmids, orot.ked) + + if self.auto: + approve = True + else: + yn = input(f"\nJoin [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: - pre = ked['i'] + pre = orot.ked['i'] if pre in self.hby.habs: ghab = self.hby.habs[pre] else: - while True: - alias = input(f"\nEnter alias for new AID: ") - if self.hby.habByName(alias) is not None: - print(f"AID alias {alias} is already in use, please try again") - else: - break + if self.auto: + alias = "test alias" + else: + while True: + alias = input(f"\nEnter alias for new AID: ") + if self.hby.habByName(alias) is not None: + print(f"AID alias {alias} is already in use, please try again") + else: + break ghab = self.hby.joinGroupHab(pre, group=alias, mhab=mhab, smids=smids, rmids=rmids) try: - serder = serdering.SerderKERI(sad=ked) - rot = ghab.rotate(serder=serder) - except ValueError as e: + ghab.rotate(serder=orot) + except ValueError: return False + rot = ghab.makeOwnEvent(allowPartiallySigned=True, sn=orot.sn) + + exn, ims = grouping.multisigRotateExn(ghab, + smids=ghab.smids, + rmids=ghab.rmids, + rot=rot) + others = list(oset(smids + (rmids or []))) + + others.remove(ghab.mhab.pre) + + for recpt in others: # this goes to other participants only as a signaling mechanism + self.postman.send(src=ghab.mhab.pre, + dest=recpt, + topic="multisig", + serder=exn, + attachment=ims) + + while not self.postman.sent(said=exn.said): + yield self.tock + + self.postman.cues.clear() + serder = serdering.SerderKERI(raw=rot) prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=serder.sn) @@ -442,8 +549,11 @@ def rpy(self, attrs): print(f" Role: {role.capitalize()}") print(f" Endpoint Provider: {endpointAlias} ({eid})") - yn = input(f"\nApprove [Y|n]? ") - approve = yn in ('', 'y', 'Y') + if self.auto: + approve = True + else: + yn = input(f"\nApprove [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: # Create and parse the event with "their" signatures @@ -502,8 +612,11 @@ def vcp(self, attrs): print(f"\nGroup Credential Regitry Creation (from {senderAlias}):") print(f"Usage: {usage}:\n") - yn = input(f"\nApprove [Y|n]? ") - approve = yn in ('', 'y', 'Y') + if self.auto: + approve = True + else: + yn = input(f"\nApprove [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: # Create and parse the event with "their" signatures @@ -597,8 +710,11 @@ def iss(self, attrs): if k not in ('d', 'i'): print(f" {k}: {v}") - yn = input(f"\nApprove [Y|n]? ") - approve = yn in ('', 'y', 'Y') + if self.auto: + approve = True + else: + yn = input(f"\nApprove [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: # Create and parse the event with "their" signatures @@ -695,8 +811,11 @@ def rev(self, attrs): else: print(f" Issued To: Unknown AID ({isse})") - yn = input(f"\nApprove Revocation [Y|n]? ") - approve = yn in ('', 'y', 'Y') + if self.auto: + approve = True + else: + yn = input(f"\nApprove Revocation [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: # Create and parse the event with "their" signatures @@ -791,8 +910,11 @@ def exn(self, attrs): else: print(f" Sending To: Unknown AID ({recp})") - yn = input(f"\nApprove [Y|n]? ") - approve = yn in ('', 'y', 'Y') + if self.auto: + approve = True + else: + yn = input(f"\nApprove [Y|n]? ") + approve = yn in ('', 'y', 'Y') if approve: eserder = serdering.SerderKERI(sad=eexn) From 3f683b3694dfbe1a5611124594922562a64c556f Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Tue, 12 Mar 2024 06:36:58 -0700 Subject: [PATCH 02/61] Version bump to 1.1.7 Signed-off-by: pfeairheller --- Makefile | 4 ++-- setup.py | 2 +- src/keri/__init__.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 48d770898..01a37f4f6 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.6 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.7 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.6 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.7 . .PHONY: publish-keri publish-keri: diff --git a/setup.py b/setup.py index de4c0b0b3..f3fdd7bde 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.6', # also change in src/keri/__init__.py + version='1.1.7', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index d39f4a1bd..0f5c0add2 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.6' # also change in setup.py +__version__ = '1.1.7' # also change in setup.py From 6495a90a8e467c101b968199bafa8fd042474200 Mon Sep 17 00:00:00 2001 From: Philip Feairheller Date: Sun, 17 Mar 2024 15:59:50 -0700 Subject: [PATCH 03/61] Update to kli multisig join command work correctly for IPEX ADMIT messages (#711) * adding command for ipex Signed-off-by: Kevin Griffin * return True in proper places for both join commands. update multisig issuer interactive command to use join for all multisig events. Signed-off-by: pfeairheller * Updates to migrate / quartet sample scripts for testing multisig migration and rotation. Signed-off-by: pfeairheller * wip Signed-off-by: Kevin Griffin * Updates to ipex kli commands and script to get `ipex join` working correctly for admit messages. Signed-off-by: pfeairheller --------- Signed-off-by: Kevin Griffin Signed-off-by: pfeairheller Co-authored-by: Kevin Griffin --- scripts/demo/basic/migrate-quadlet.sh | 21 +- scripts/demo/basic/rotate-new-quartet.sh | 8 +- .../multisig-grant-multisig-admit.sh | 141 +++++++++ .../multisig-issuer-interactive.sh | 11 +- scripts/demo/credentials/multisig-issuer.sh | 2 +- scripts/demo/data/issuee-1-sample.json | 14 + scripts/demo/data/issuee-2-sample.json | 14 + scripts/demo/data/issuee-multisig-sample.json | 15 + scripts/demo/data/issuer-1-sample.json | 13 + scripts/demo/data/issuer-2-sample.json | 13 + scripts/demo/data/issuer-multisig-sample.json | 15 + src/keri/app/cli/commands/ipex/admit.py | 25 +- src/keri/app/cli/commands/ipex/grant.py | 2 +- src/keri/app/cli/commands/ipex/join.py | 275 ++++++++++++++++++ src/keri/app/cli/commands/multisig/join.py | 96 +----- src/keri/app/cli/commands/time.py | 25 ++ src/keri/vc/protocoling.py | 5 +- 17 files changed, 579 insertions(+), 116 deletions(-) create mode 100755 scripts/demo/credentials/multisig-grant-multisig-admit.sh create mode 100644 scripts/demo/data/issuee-1-sample.json create mode 100644 scripts/demo/data/issuee-2-sample.json create mode 100644 scripts/demo/data/issuee-multisig-sample.json create mode 100644 scripts/demo/data/issuer-1-sample.json create mode 100644 scripts/demo/data/issuer-2-sample.json create mode 100644 scripts/demo/data/issuer-multisig-sample.json create mode 100644 src/keri/app/cli/commands/ipex/join.py create mode 100644 src/keri/app/cli/commands/time.py diff --git a/scripts/demo/basic/migrate-quadlet.sh b/scripts/demo/basic/migrate-quadlet.sh index 5339ffcec..b175996eb 100755 --- a/scripts/demo/basic/migrate-quadlet.sh +++ b/scripts/demo/basic/migrate-quadlet.sh @@ -1,13 +1,14 @@ #!/bin/bash -kli migrate --name multisig1 -kli migrate --name multisig2 -kli migrate --name multisig3 -kli migrate --name multisig4 +kli migrate --name delegator --force +kli migrate --name multisig1 --force +kli migrate --name multisig2 --force +kli migrate --name multisig3 --force +kli migrate --name multisig4 --force -kli migrate --name wil -kli migrate --name wan -kli migrate --name wes -kli migrate --name wit -kli migrate --name wub -kli migrate --name wyz \ No newline at end of file +kli migrate --name wil --force +kli migrate --name wan --force +kli migrate --name wes --force +kli migrate --name wit --force +kli migrate --name wub --force +kli migrate --name wyz --force \ No newline at end of file diff --git a/scripts/demo/basic/rotate-new-quartet.sh b/scripts/demo/basic/rotate-new-quartet.sh index 33c0b83b9..83ea76a48 100755 --- a/scripts/demo/basic/rotate-new-quartet.sh +++ b/scripts/demo/basic/rotate-new-quartet.sh @@ -7,8 +7,8 @@ kli query --name multisig1 --alias multisig1 --prefix EJccSRTfXYF6wrUVuenAIHzwcx # Perform rotation of mulisig AID from local kli AIDs that roll themselves out and the new AIDs in kli multisig rotate --name multisig1 --alias multisig \ - --smids EKYLUMmNPZeEs77Zvclf0bSN5IN-mLfLpx2ySb-HDlk4:2 \ - --smids EJccSRTfXYF6wrUVuenAIHzwcx3hJugeiJsEKmndi5q1:2 \ + --smids EKYLUMmNPZeEs77Zvclf0bSN5IN-mLfLpx2ySb-HDlk4:1 \ + --smids EJccSRTfXYF6wrUVuenAIHzwcx3hJugeiJsEKmndi5q1:1 \ --smids EBFg-5SGDCv5YfwpkArWRBdTxNRUXU8uVcDKNzizOQZc:0 \ --smids EBmW2bXbgsP3HITwW3FmITzAb3wVmHlxCusZ46vgGgP5:0 \ --smids EL4RpdS2Atb2Syu5xLdpz9CcNNYoFUUDlLHxHD09vcgh:0 \ @@ -22,8 +22,8 @@ kli multisig rotate --name multisig1 --alias multisig \ pid=$! PID_LIST="$pid" kli multisig rotate --name multisig2 --alias multisig \ - --smids EKYLUMmNPZeEs77Zvclf0bSN5IN-mLfLpx2ySb-HDlk4:2 \ - --smids EJccSRTfXYF6wrUVuenAIHzwcx3hJugeiJsEKmndi5q1:2 \ + --smids EKYLUMmNPZeEs77Zvclf0bSN5IN-mLfLpx2ySb-HDlk4:1 \ + --smids EJccSRTfXYF6wrUVuenAIHzwcx3hJugeiJsEKmndi5q1:1 \ --smids EBFg-5SGDCv5YfwpkArWRBdTxNRUXU8uVcDKNzizOQZc:0 \ --smids EBmW2bXbgsP3HITwW3FmITzAb3wVmHlxCusZ46vgGgP5:0 \ --smids EL4RpdS2Atb2Syu5xLdpz9CcNNYoFUUDlLHxHD09vcgh:0 \ diff --git a/scripts/demo/credentials/multisig-grant-multisig-admit.sh b/scripts/demo/credentials/multisig-grant-multisig-admit.sh new file mode 100755 index 000000000..713e93085 --- /dev/null +++ b/scripts/demo/credentials/multisig-grant-multisig-admit.sh @@ -0,0 +1,141 @@ +#!/bin/bash +# To run this script you need to run the following command in separate terminals: +# > kli witness demo +# and from the vLEI repo run: +# > vLEI-server -s ./schema/acdc -c ./samples/acdc/ -o ./samples/oobis/ +# + +# issuer 1 +# EEVlFHcMWAQNwezHjyKK5cKKzF6zgLlnrLyi_CcAEXCs +# issuer 2 +# EFJtDtSoE6XOOqLoLvYoB7ctCzMtJDiAJltnXiK_EdlM +# issuee 1 +# EI0IoYyHxXc7_uQyaN2WocSC3lRZsvrDAPbREOw7fM0_ +# issuee 2 +# EPw5WQAFcNXXSbg_pTKgh8-K_rfXnD1uDKS13OeNHkKE +# issuer group +# ELrnb8aI_wy2q_sSbCAwkgy2kOdMpRI1urFrhQiMJGLW +# issuee group +# ELkmm28zQEyxkryJZQ4WVT4fjukklM4dR91l2DQfQHZK + +# Create local environments for issuer group +kli init --name issuer1 --salt 0ACDEyMzQ1Njc4OWxtbm9aBc --nopasscode --config-dir ${KERI_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name issuer1 --alias issuer1 --file ${KERI_DEMO_SCRIPT_DIR}/data/issuer-1-sample.json + +# Incept both local identifiers for issuer group +kli init --name issuer2 --salt 0ACDEyMzQ1Njc4OWdoaWpsaw --nopasscode --config-dir ${KERI_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name issuer2 --alias issuer2 --file ${KERI_DEMO_SCRIPT_DIR}/data/issuer-2-sample.json + +# Exchange OOBIs between issuer group +kli oobi resolve --name issuer1 --oobi-alias issuer2 --oobi http://127.0.0.1:5642/oobi/EFJtDtSoE6XOOqLoLvYoB7ctCzMtJDiAJltnXiK_EdlM/witness +kli oobi resolve --name issuer2 --oobi-alias issuer1 --oobi http://127.0.0.1:5642/oobi/EEVlFHcMWAQNwezHjyKK5cKKzF6zgLlnrLyi_CcAEXCs/witness + +# Create the identifier to which the credential will be issued +kli init --name issuee1 --salt 0ACDEyMzQ1Njc4OWxtbm9qWc --nopasscode --config-dir ${KERI_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name issuee1 --alias issuee1 --file ${KERI_DEMO_SCRIPT_DIR}/data/issuee-1-sample.json + +# Create the identifier to which the credential will be issued +kli init --name issuee2 --salt 0ACDEyMzQ1Njc4OWxtbm9qWc --nopasscode --config-dir ${KERI_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name issuee2 --alias issuee2 --file ${KERI_DEMO_SCRIPT_DIR}/data/issuee-2-sample.json + +# Exchange OOBIs between issuee group +kli oobi resolve --name issuee1 --oobi-alias issuee2 --oobi http://127.0.0.1:5642/oobi/EPw5WQAFcNXXSbg_pTKgh8-K_rfXnD1uDKS13OeNHkKE/witness +kli oobi resolve --name issuee2 --oobi-alias issuee1 --oobi http://127.0.0.1:5642/oobi/EI0IoYyHxXc7_uQyaN2WocSC3lRZsvrDAPbREOw7fM0_/witness + +# Introduce issuer to issuee +kli oobi resolve --name issuee1 --oobi-alias issuer1 --oobi http://127.0.0.1:5642/oobi/EEVlFHcMWAQNwezHjyKK5cKKzF6zgLlnrLyi_CcAEXCs/witness +kli oobi resolve --name issuee2 --oobi-alias issuer1 --oobi http://127.0.0.1:5642/oobi/EEVlFHcMWAQNwezHjyKK5cKKzF6zgLlnrLyi_CcAEXCs/witness +kli oobi resolve --name issuee1 --oobi-alias issuer2 --oobi http://127.0.0.1:5642/oobi/EFJtDtSoE6XOOqLoLvYoB7ctCzMtJDiAJltnXiK_EdlM/witness +kli oobi resolve --name issuee2 --oobi-alias issuer2 --oobi http://127.0.0.1:5642/oobi/EFJtDtSoE6XOOqLoLvYoB7ctCzMtJDiAJltnXiK_EdlM/witness + +# Introduce the issuee to issuer +kli oobi resolve --name issuer1 --oobi-alias issuee1 --oobi http://127.0.0.1:5642/oobi/EI0IoYyHxXc7_uQyaN2WocSC3lRZsvrDAPbREOw7fM0_/witness +kli oobi resolve --name issuer2 --oobi-alias issuee1 --oobi http://127.0.0.1:5642/oobi/EI0IoYyHxXc7_uQyaN2WocSC3lRZsvrDAPbREOw7fM0_/witness +kli oobi resolve --name issuer1 --oobi-alias issuee2 --oobi http://127.0.0.1:5642/oobi/EPw5WQAFcNXXSbg_pTKgh8-K_rfXnD1uDKS13OeNHkKE/witness +kli oobi resolve --name issuer2 --oobi-alias issuee2 --oobi http://127.0.0.1:5642/oobi/EPw5WQAFcNXXSbg_pTKgh8-K_rfXnD1uDKS13OeNHkKE/witness + +## Load Data OOBI for schema of credential to issue +kli oobi resolve --name issuer1 --oobi-alias vc --oobi http://127.0.0.1:7723/oobi/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao +kli oobi resolve --name issuer2 --oobi-alias vc --oobi http://127.0.0.1:7723/oobi/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao +kli oobi resolve --name issuee1 --oobi-alias vc --oobi http://127.0.0.1:7723/oobi/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao +kli oobi resolve --name issuee2 --oobi-alias vc --oobi http://127.0.0.1:7723/oobi/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao + +# Run the follow in parallel and wait for the issuer group to be created: +kli multisig incept --name issuer1 --alias issuer1 --group issuer --file ${KERI_DEMO_SCRIPT_DIR}/data/issuer-multisig-sample.json & +pid=$! +PID_LIST+=" $pid" + +kli multisig join --name issuer2 +pid=$! +PID_LIST+=" $pid" + +wait $PID_LIST + +# Run the follow in parallel and wait for the issuee group to be created: +kli multisig incept --name issuee1 --alias issuee1 --group issuee --file ${KERI_DEMO_SCRIPT_DIR}/data/issuee-multisig-sample.json & +pid=$! +PID_LIST+=" $pid" + +kli multisig join --name issuee2 +pid=$! +PID_LIST+=" $pid" + +wait $PID_LIST + +# Introduce issuer issuer issuer to issuees +kli oobi resolve --name issuer1 --oobi-alias issuee --oobi http://127.0.0.1:5642/oobi/ELkmm28zQEyxkryJZQ4WVT4fjukklM4dR91l2DQfQHZK/witness +kli oobi resolve --name issuer2 --oobi-alias issuee --oobi http://127.0.0.1:5642/oobi/ELkmm28zQEyxkryJZQ4WVT4fjukklM4dR91l2DQfQHZK/witness + +kli oobi resolve --name issuee1 --oobi-alias issuer --oobi http://127.0.0.1:5642/oobi/ELrnb8aI_wy2q_sSbCAwkgy2kOdMpRI1urFrhQiMJGLW/witness +kli oobi resolve --name issuee2 --oobi-alias issuer --oobi http://127.0.0.1:5642/oobi/ELrnb8aI_wy2q_sSbCAwkgy2kOdMpRI1urFrhQiMJGLW/witness + +# Create a credential registry owned by the issuer issuer +kli vc registry incept --name issuer1 --alias issuer --registry-name vLEI --usage "Issue vLEIs" --nonce AHSNDV3ABI6U8OIgKaj3aky91ZpNL54I5_7-qwtC6q2s & +pid=$! +PID_LIST=" $pid" + +echo "issuer2 looking to join credential registry creation" +kli multisig join --name issuer2 + +wait $PID_LIST + +# Issue Credential +kli vc create --name issuer1 --alias issuer --registry-name vLEI --schema EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao --recipient ELkmm28zQEyxkryJZQ4WVT4fjukklM4dR91l2DQfQHZK --data @${KERI_DEMO_SCRIPT_DIR}/data/credential-data.json & +pid=$! +PID_LIST+=" $pid" + +echo "issuer2 looking to join credential creation" +kli multisig join --name issuer2 + +wait $PID_LIST + +SAID=$(kli vc list --name issuer1 --alias issuer --issued --said) + +kli ipex grant --name issuer1 --alias issuer --said "${SAID}" --recipient ELkmm28zQEyxkryJZQ4WVT4fjukklM4dR91l2DQfQHZK & +pid=$! +PID_LIST="$pid" + +kli ipex join --name issuer2 + +wait ${PID_LIST} + +echo "Polling for issuee1's IPEX message..." +SAID=$(kli ipex list --name issuee1 --alias issuee1 --poll --said | sed -n '1 p') + +echo "Polling for issuee2's IPEX message..." +kli ipex list --name issuee2 --alias issuee2 --poll --said + +echo "Issuee1 Admitting GRANT ${SAID}" +kli ipex admit --name issuee1 --alias issuee --said "${SAID}" & +pid=$! +PID_LIST="$pid" + +echo "Issuee2 Admitting GRANT ${SAID}" +kli ipex join --name issuee2 + +wait ${PID_LIST} + +kli vc list --name issuee1 --alias issuee + +echo "Issuer1 checking for ADMIT" +kli ipex list --name issuer1 --alias issuer --poll diff --git a/scripts/demo/credentials/multisig-issuer-interactive.sh b/scripts/demo/credentials/multisig-issuer-interactive.sh index 281d1bb6b..c26b265d0 100755 --- a/scripts/demo/credentials/multisig-issuer-interactive.sh +++ b/scripts/demo/credentials/multisig-issuer-interactive.sh @@ -39,9 +39,12 @@ kli multisig incept --name multisig1 --alias multisig1 --group multisig --file $ pid=$! PID_LIST+=" $pid" -kli multisig incept --name multisig2 --alias multisig2 --group multisig --file ${KERI_DEMO_SCRIPT_DIR}/data/multisig-sample.json & -pid=$! -PID_LIST+=" $pid" +#kli multisig incept --name multisig2 --alias multisig2 --group multisig --file ${KERI_DEMO_SCRIPT_DIR}/data/multisig-sample.json & +#pid=$! +#PID_LIST+=" $pid" +# +echo "Multisig2 looking to join inception event" +kli multisig join --name multisig2 wait $PID_LIST kli oobi resolve --name holder --oobi-alias multisig --oobi http://127.0.0.1:5642/oobi/EC61gZ9lCKmHAS7U5ehUfEbGId5rcY0D7MirFZHDQcE2/witness @@ -77,7 +80,7 @@ kli ipex grant --name multisig1 --alias multisig --said "${SAID}" --recipient EL pid=$! PID_LIST="$pid" -kli multisig join --name multisig2 +kli ipex join --name multisig2 wait ${PID_LIST} diff --git a/scripts/demo/credentials/multisig-issuer.sh b/scripts/demo/credentials/multisig-issuer.sh index 69b2da044..a9f550669 100755 --- a/scripts/demo/credentials/multisig-issuer.sh +++ b/scripts/demo/credentials/multisig-issuer.sh @@ -102,7 +102,7 @@ echo "Polling for holder's IPEX message..." SAID=$(kli ipex list --name holder --alias holder --poll --said) echo "Admitting GRANT ${SAID}" -kli ipex admit --name holder --alias holder --said "${SAID}" +kli ipex admit --name holder --alias holder --said "${SAID}" --time "${TIME}" kli vc list --name holder --alias holder --poll diff --git a/scripts/demo/data/issuee-1-sample.json b/scripts/demo/data/issuee-1-sample.json new file mode 100644 index 000000000..8cd480e60 --- /dev/null +++ b/scripts/demo/data/issuee-1-sample.json @@ -0,0 +1,14 @@ +{ + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 2, + "icount": 1, + "ncount": 1, + "isith": "1", + "nsith": "1" +} + diff --git a/scripts/demo/data/issuee-2-sample.json b/scripts/demo/data/issuee-2-sample.json new file mode 100644 index 000000000..8cd480e60 --- /dev/null +++ b/scripts/demo/data/issuee-2-sample.json @@ -0,0 +1,14 @@ +{ + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 2, + "icount": 1, + "ncount": 1, + "isith": "1", + "nsith": "1" +} + diff --git a/scripts/demo/data/issuee-multisig-sample.json b/scripts/demo/data/issuee-multisig-sample.json new file mode 100644 index 000000000..4866b0a1c --- /dev/null +++ b/scripts/demo/data/issuee-multisig-sample.json @@ -0,0 +1,15 @@ +{ + "aids": [ + "EI0IoYyHxXc7_uQyaN2WocSC3lRZsvrDAPbREOw7fM0_", + "EPw5WQAFcNXXSbg_pTKgh8-K_rfXnD1uDKS13OeNHkKE" + ], + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 3, + "isith": "2", + "nsith": "2" +} diff --git a/scripts/demo/data/issuer-1-sample.json b/scripts/demo/data/issuer-1-sample.json new file mode 100644 index 000000000..ad8882295 --- /dev/null +++ b/scripts/demo/data/issuer-1-sample.json @@ -0,0 +1,13 @@ +{ + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 2, + "icount": 1, + "ncount": 1, + "isith": "1", + "nsith": "1" +} diff --git a/scripts/demo/data/issuer-2-sample.json b/scripts/demo/data/issuer-2-sample.json new file mode 100644 index 000000000..ad8882295 --- /dev/null +++ b/scripts/demo/data/issuer-2-sample.json @@ -0,0 +1,13 @@ +{ + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 2, + "icount": 1, + "ncount": 1, + "isith": "1", + "nsith": "1" +} diff --git a/scripts/demo/data/issuer-multisig-sample.json b/scripts/demo/data/issuer-multisig-sample.json new file mode 100644 index 000000000..6afab98c3 --- /dev/null +++ b/scripts/demo/data/issuer-multisig-sample.json @@ -0,0 +1,15 @@ +{ + "aids": [ + "EEVlFHcMWAQNwezHjyKK5cKKzF6zgLlnrLyi_CcAEXCs", + "EFJtDtSoE6XOOqLoLvYoB7ctCzMtJDiAJltnXiK_EdlM" + ], + "transferable": true, + "wits": [ + "BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha", + "BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM", + "BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX" + ], + "toad": 3, + "isith": "2", + "nsith": "2" +} diff --git a/src/keri/app/cli/commands/ipex/admit.py b/src/keri/app/cli/commands/ipex/admit.py index f45918aa2..842533805 100644 --- a/src/keri/app/cli/commands/ipex/admit.py +++ b/src/keri/app/cli/commands/ipex/admit.py @@ -31,6 +31,7 @@ parser.add_argument("--said", "-s", help="SAID of the exn grant message to admit", required=True) parser.add_argument("--message", "-m", help="optional human readable message to " "send to recipient", required=False, default="") +parser.add_argument("--time", help="timestamp", required=False, default=None) def handler(args): @@ -39,15 +40,17 @@ def handler(args): base=args.base, bran=args.bran, said=args.said, - message=args.message) + message=args.message, + timestamp=args.time) return [ed] class AdmitDoer(doing.DoDoer): - def __init__(self, name, alias, base, bran, said, message): + def __init__(self, name, alias, base, bran, said, message, timestamp ): self.said = said self.message = message + self.timestamp = timestamp self.hby = existing.setupHby(name=name, base=base, bran=bran) self.hab = self.hby.habByName(alias) self.rgy = credentialing.Regery(hby=self.hby, name=name, base=base) @@ -118,31 +121,36 @@ def admitDo(self, tymth, tock=0.0): yield self.tock recp = grant.ked['i'] - exn, atc = protocoling.ipexAdmitExn(hab=self.hab, message=self.message, grant=grant) + exn, atc = protocoling.ipexAdmitExn(hab=self.hab, message=self.message, grant=grant, dt=self.timestamp) msg = bytearray(exn.raw) msg.extend(atc) parsing.Parser().parseOne(ims=bytes(msg), exc=self.exc) + sender = self.hab if isinstance(self.hab, habbing.GroupHab): + sender = self.hab.mhab wexn, watc = grouping.multisigExn(self.hab, exn=msg) smids = self.hab.db.signingMembers(pre=self.hab.pre) smids.remove(self.hab.mhab.pre) - for recp in smids: # this goes to other participants only as a signaling mechanism - postman = forwarding.StreamPoster(hby=self.hby, hab=self.hab.mhab, recp=recp, topic="multisig") + for part in smids: # this goes to other participants only as a signaling mechanism + postman = forwarding.StreamPoster(hby=self.hby, hab=self.hab.mhab, recp=part, topic="multisig") postman.send(serder=wexn, attachment=watc) doer = doing.DoDoer(doers=postman.deliver()) self.extend([doer]) - while not self.exc.complete(said=wexn.said): + while not self.exc.complete(said=exn.said): yield self.tock if self.exc.lead(self.hab, said=exn.said): print(f"Sending admit message to {recp}") - postman = forwarding.StreamPoster(hby=self.hby, hab=self.hab, recp=recp, topic="credential") + postman = forwarding.StreamPoster(hby=self.hby, hab=sender, recp=recp, topic="credential") + + atc = exchanging.serializeMessage(self.hby, exn.said) + del atc[:exn.size] postman.send(serder=exn, attachment=atc) @@ -152,4 +160,7 @@ def admitDo(self, tymth, tock=0.0): while not doer.done: yield self.tock + print(f"... admit message sent") + self.remove([doer]) + self.remove(self.toRemove) diff --git a/src/keri/app/cli/commands/ipex/grant.py b/src/keri/app/cli/commands/ipex/grant.py index ba9dcb232..38fc0d33b 100644 --- a/src/keri/app/cli/commands/ipex/grant.py +++ b/src/keri/app/cli/commands/ipex/grant.py @@ -162,6 +162,6 @@ def grantDo(self, tymth, tock=0.0): yield self.tock print(f"... grant message sent") - self.remove([postman]) + self.remove([doer]) self.remove(self.toRemove) diff --git a/src/keri/app/cli/commands/ipex/join.py b/src/keri/app/cli/commands/ipex/join.py new file mode 100644 index 000000000..0f8401514 --- /dev/null +++ b/src/keri/app/cli/commands/ipex/join.py @@ -0,0 +1,275 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands.ipex module + +Join multisig ipex messages +""" +import argparse + +from hio.base import doing + +from keri import help +from keri.app import habbing, indirecting, agenting, notifying, grouping, connecting, forwarding +from keri.app.cli.common import existing +from keri.core import parsing, routing, serdering, coring +from keri.peer import exchanging +from keri.vdr import verifying, credentialing + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Join group multisig ipex events') +parser.set_defaults(handler=lambda args: join(args)) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran +parser.add_argument("--auto", "-Y", help="auto approve any delegation request non-interactively", action="store_true") + + +def join(args): + """ Wait for and provide interactive confirmation of group multisig inception, rotation or interaction events + + Parameters: + args(Namespace): parsed arguements namespace object + + """ + name = args.name + base = args.base + bran = args.bran + auto = args.auto + + joinDoer = JoinDoer(name=name, base=base, bran=bran, auto=auto) + + doers = [joinDoer] + return doers + + +class JoinDoer(doing.DoDoer): + """ Doist doer capable of polling for group ipex events and prompting user for action + + """ + + def __init__(self, name, base, bran, auto=False): + """ Create doer for polling for group ipex events and either approve automatically or prompt user + + Parameters: + name (str): database environment name + base (str): database directory prefix + bran (str): passcode to unlock keystore + + """ + self.hby = existing.setupHby(name=name, base=base, bran=bran) + self.rgy = credentialing.Regery(hby=self.hby, name=name, base=base) + self.hbyDoer = habbing.HaberyDoer(habery=self.hby) # setup doer + self.witq = agenting.WitnessInquisitor(hby=self.hby) + self.org = connecting.Organizer(hby=self.hby) + self.notifier = notifying.Notifier(hby=self.hby) + self.exc = exchanging.Exchanger(hby=self.hby, handlers=[]) + self.verifier = verifying.Verifier(hby=self.hby, reger=self.rgy.reger) + self.rvy = routing.Revery(db=self.hby.db, lax=True) + self.hby.kvy.registerReplyRoutes(self.rvy.rtr) + self.psr = parsing.Parser(kvy=self.hby.kvy, tvy=self.rgy.tvy, rvy=self.rvy, vry=self.verifier, exc=self.exc) + + mux = grouping.Multiplexor(hby=self.hby, notifier=self.notifier) + grouping.loadHandlers(exc=self.exc, mux=mux) + self.counselor = grouping.Counselor(hby=self.hby) + + self.registrar = credentialing.Registrar(hby=self.hby, rgy=self.rgy, counselor=self.counselor) + self.credentialer = credentialing.Credentialer(hby=self.hby, rgy=self.rgy, registrar=self.registrar, + verifier=self.verifier) + + self.mbx = indirecting.MailboxDirector(hby=self.hby, exc=self.exc, topics=['/receipt', '/multisig', '/replay', + '/delegate']) + self.postman = forwarding.Poster(hby=self.hby) + + doers = [self.hbyDoer, self.witq, self.mbx, self.counselor, self.registrar, self.credentialer, self.postman] + self.toRemove = list(doers) + doers.extend([doing.doify(self.joinDo)]) + self.auto = auto + super(JoinDoer, self).__init__(doers=doers) + + def joinDo(self, tymth, tock=0.0): + """ + Parameters: + tymth (function): injected function wrapper closure returned by .tymen() of + Tymist instance. Calling tymth() returns associated Tymist .tyme. + tock (float): injected initial tock value + + Returns: doifiable Doist compatible generator method + """ + # enter context + self.wind(tymth) + self.tock = tock + _ = (yield self.tock) + + print("Waiting for group ipex events...") + + while True: + + found = False + for keys, notice in self.notifier.noter.notes.getItemIter(): + attrs = notice.attrs + route = attrs['r'] + + if route == '/multisig/exn': + said = attrs["d"] + exn, pathed = exchanging.cloneMessage(self.hby, said=said) + embeds = exn.ked['e'] + + if embeds['exn']['r'].startswith("/ipex"): + done = yield from self.ipex(exn, pathed) + + if done: + self.notifier.noter.notes.rem(keys=keys) + + else: + delete = input(f"\nDelete event [Y|n]? ") + if delete in ("Y", "y"): + self.notifier.noter.notes.rem(keys=keys) + found = True + if found: + break + + yield self.tock + + self.remove(self.toRemove) + + def ipex(self, exn, pathed): + """ Handle exn messages for ipex + + Parameters: + exn (SerderKERI): exn message + pathed (dict): pathed attachments dict + + Returns: + + """ + embeds = exn.ked['e'] + sender = exn.ked['i'] + + contact = self.org.get(sender) + senderAlias = contact['alias'] + + eexn = embeds['exn'] + + route = eexn['r'] + + group = eexn["i"] + hab = self.hby.habs[group] if group in self.hby.habs else None + if hab is None: + raise ValueError(f"message sender not a valid AID={group}") + + print() + print(f"Group IPEX Message proposal (from {senderAlias}):") + print(f" Message Type: {eexn['r']}") + print(f" Message SAID: {eexn['d']}") + print(f" Sending From: {hab.name} ({hab.pre})") + + match route: + case "/ipex/admit": + recp = yield from self.getAdmitRecp(eexn) + case "/ipex/agree": + recp = self.getAgreeRecp(eexn) + case "/ipex/apply": + recp = self.getApplyRecp(eexn) + case "/ipex/grant": + recp = self.getGrantRecp(eexn) + case "/ipex/offer": + recp = self.getOfferRecp(eexn) + case "/ipex/spurn": + recp = self.getSpurnRecp(eexn) + case _: + return False + + contact = self.org.get(recp) + if contact is not None and "alias" in contact: + print(f" Sending To: {contact['alias']} ({recp})") + else: + print(f" Sending To: Unknown AID ({recp})") + + if self.auto: + approve = True + else: + yn = input(f"\nApprove [Y|n]? ") + approve = yn in ('', 'y', 'Y') + + if approve: + eserder = serdering.SerderKERI(sad=eexn) + anc = bytearray(eserder.raw) + pathed["exn"] + self.psr.parseOne(ims=bytes(anc)) + + msg = hab.endorse(serder=eserder, last=False, pipelined=False) + msg = msg + pathed["exn"] + self.psr.parseOne(ims=bytes(msg)) + + smids = hab.db.signingMembers(pre=hab.pre) + smids.remove(hab.mhab.pre) + + for smid in smids: # this goes to other participants only as a signaling mechanism + rexn, atc = grouping.multisigExn(ghab=hab, exn=msg) + self.postman.send(src=hab.mhab.pre, + dest=smid, + topic="multisig", + serder=rexn, + attachment=atc) + while not self.postman.sent(said=rexn.said): + yield self.tock + + while not self.exc.complete(said=eserder.said): + self.exc.processEscrow() + yield self.tock + + if self.exc.lead(hab, said=exn.said): + print(f"Sending message {eserder.said} to {recp}") + atc = exchanging.serializeMessage(self.hby, eserder.said) + del atc[:eserder.size] + self.postman.send(src=hab.mhab.pre, + dest=recp, + topic="credential", + serder=eserder, + attachment=atc) + + while not self.postman.sent(said=eserder.said): + yield self.tock + + print("... ipex message sent") + return True + + return True + return False + + def getAdmitRecp(self, exn): + grant, pathed = exchanging.cloneMessage(self.hby, exn['p']) + if grant is None: + raise ValueError(f"exn message said={exn['p']} not found") + + embeds = grant.ked['e'] + acdc = embeds["acdc"] + for label in ("anc", "iss", "acdc"): + ked = embeds[label] + sadder = coring.Sadder(ked=ked) + ims = bytearray(sadder.raw) + pathed[label] + self.psr.parseOne(ims=ims) + + said = acdc["d"] + while not self.rgy.reger.saved.get(keys=said): + yield self.tock + + return acdc['i'] + + def getAgreeRecp(self, exn): + pass + + def getApplyRecp(self, exn): + return exn['a']['i'] + + def getGrantRecp(self, exn): + return exn['a']['i'] + + def getOfferRecp(self, exn): + pass + + def getSpurnRecp(self, exn): + pass diff --git a/src/keri/app/cli/commands/multisig/join.py b/src/keri/app/cli/commands/multisig/join.py index e144c2c7b..94b1e058e 100644 --- a/src/keri/app/cli/commands/multisig/join.py +++ b/src/keri/app/cli/commands/multisig/join.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- """ KERI -keri.kli.commands.delegate module +keri.kli.commands.multisig module """ import argparse @@ -130,8 +130,6 @@ def confirmDo(self, tymth, tock=0.0): done = yield from self.iss(attrs) case '/multisig/rev': done = yield from self.rev(attrs) - case '/multisig/exn': - done = yield from self.exn(attrs) case _: continue @@ -582,8 +580,9 @@ def rpy(self, attrs): yield self.tock print(f"End role authorization added for role {role}") + return True - yield self.tock + return False def vcp(self, attrs): """ Handle issue messages @@ -658,8 +657,9 @@ def vcp(self, attrs): yield self.tock print(f"Registry {vserder.pre} created.") + return True - yield self.tock + return False def iss(self, attrs): """ Handle issue messages @@ -760,8 +760,9 @@ def iss(self, attrs): yield self.tock print(f"Credential {creder.said} complete.") + return True - yield self.tock + return False def rev(self, attrs): """ Handle revocation messages @@ -874,85 +875,6 @@ def rev(self, attrs): while not self.postman.sent(said=last.said): yield self.tock - yield self.tock - - def exn(self, attrs): - """ Handle exn messages - - Parameters: - attrs (dict): attributes of the reply message - - Returns: - - """ - said = attrs["d"] - exn, pathed = exchanging.cloneMessage(self.hby, said=said) - embeds = exn.ked['e'] - sender = exn.ked['i'] - - contact = self.org.get(sender) - senderAlias = contact['alias'] - - eexn = embeds['exn'] - - group = eexn["i"] - hab = self.hby.habs[group] if group in self.hby.habs else None - if hab is None: - raise ValueError(f"message sender not a valid AID={group}") - - print(f"Group Peer-2-Peer Message proposal (from {senderAlias}):") - print(f" Message Type: {eexn['r']}") - print(f" Sending From: {hab.name} ({hab.pre})") - recp = eexn['a']['i'] - contact = self.org.get(recp) - if contact is not None and "alias" in contact: - print(f" Sending To: {contact['alias']} ({recp})") - else: - print(f" Sending To: Unknown AID ({recp})") - - if self.auto: - approve = True - else: - yn = input(f"\nApprove [Y|n]? ") - approve = yn in ('', 'y', 'Y') - - if approve: - eserder = serdering.SerderKERI(sad=eexn) - anc = bytearray(eserder.raw) + pathed["exn"] - self.psr.parseOne(ims=bytes(anc)) - - msg = hab.endorse(serder=eserder, last=False, pipelined=False) - msg = msg + pathed["exn"] - self.psr.parseOne(ims=bytes(msg)) - - smids = hab.db.signingMembers(pre=hab.pre) - smids.remove(hab.mhab.pre) - - for smid in smids: # this goes to other participants only as a signaling mechanism - rexn, atc = grouping.multisigExn(ghab=hab, exn=msg) - self.postman.send(src=hab.mhab.pre, - dest=smid, - topic="multisig", - serder=rexn, - attachment=atc) - - while not self.exc.complete(said=eserder.said): - self.exc.processEscrow() - yield self.tock - - if self.exc.lead(hab.mhab, said=exn.said): - print(f"Sending message {eserder.said} to {recp}") - atc = exchanging.serializeMessage(self.hby, eserder.said) - del atc[:eserder.size] - self.postman.send(src=hab.mhab.pre, - dest=recp, - topic="credential", - serder=eserder, - attachment=atc) - - while not self.postman.sent(said=eserder.said): - yield self.tock - - print("... grant message sent") + return True - yield self.tock + return False diff --git a/src/keri/app/cli/commands/time.py b/src/keri/app/cli/commands/time.py new file mode 100644 index 000000000..fa48a1638 --- /dev/null +++ b/src/keri/app/cli/commands/time.py @@ -0,0 +1,25 @@ +# -*- encoding: utf-8 -*- +""" +keri.app.cli.commands module + +""" +import argparse + +from hio.base import doing + +from keri.help import helping + +parser = argparse.ArgumentParser(description='Print a new time') +parser.set_defaults(handler=lambda args: handler(args)) + + +def handler(_): + return [doing.doify(time)] + + +def time(tymth, tock=0.0): + """ time + """ + _ = (yield tock) + + print(helping.nowIso8601()) diff --git a/src/keri/vc/protocoling.py b/src/keri/vc/protocoling.py index 12f4c991b..65900e6cb 100644 --- a/src/keri/vc/protocoling.py +++ b/src/keri/vc/protocoling.py @@ -264,13 +264,14 @@ def ipexGrantExn(hab, recp, message, acdc, iss=None, anc=None, agree=None, dt=No return exn, ims -def ipexAdmitExn(hab, message, grant): +def ipexAdmitExn(hab, message, grant, dt=None): """ Admit a disclosure Parameters: hab(Hab): identifier environment for issuer of credential message(str): Human readable message regarding the admission grant (Serder): IPEX grant exn message serder + dt (str): timestamp Returns: Serder: credential issuance exn peer to peer message @@ -281,7 +282,7 @@ def ipexAdmitExn(hab, message, grant): m=message, ) - exn, end = exchanging.exchange(route="/ipex/admit", payload=data, sender=hab.pre, dig=grant.said) + exn, end = exchanging.exchange(route="/ipex/admit", payload=data, sender=hab.pre, dig=grant.said, date=dt) ims = hab.endorse(serder=exn, last=False, pipelined=False) del ims[:exn.size] ims.extend(end) From 1fe921408c2cc261c139b3e22baac26e27de8039 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Sun, 17 Mar 2024 16:26:01 -0700 Subject: [PATCH 04/61] Version bump Signed-off-by: pfeairheller --- Makefile | 4 ++-- setup.py | 2 +- src/keri/__init__.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 01a37f4f6..0befb65e3 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.7 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.8 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.7 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.8 . .PHONY: publish-keri publish-keri: diff --git a/setup.py b/setup.py index f3fdd7bde..d3b4c467a 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.7', # also change in src/keri/__init__.py + version='1.1.8', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 0f5c0add2..31d78b34b 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.7' # also change in setup.py +__version__ = '1.1.8' # also change in setup.py From c97212de9f3af96810135fbc140bd4746e4120b9 Mon Sep 17 00:00:00 2001 From: tsterker Date: Mon, 25 Mar 2024 23:13:40 +0100 Subject: [PATCH 05/61] docs: update docker run command for locally built image (#724) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e9771724..0b432d6fc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run -it gleif/keri /bin/bash` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.8` and you can run `kli version` from within the running container to play with KERIpy. + +Make sure the image tag matches the version used in the `Makefile`. +We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. ### Dependencies #### Binaries From d18fe3f29996e027fd0fc30df2844cafc9bd2c54 Mon Sep 17 00:00:00 2001 From: Philip Feairheller Date: Tue, 26 Mar 2024 16:28:00 -0700 Subject: [PATCH 06/61] Add support for the --send argument back into `kli revoke`. It got clobbered in a merge. (#725) Signed-off-by: pfeairheller --- src/keri/app/cli/commands/vc/revoke.py | 32 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/keri/app/cli/commands/vc/revoke.py b/src/keri/app/cli/commands/vc/revoke.py index ed2c41ec9..a37059255 100644 --- a/src/keri/app/cli/commands/vc/revoke.py +++ b/src/keri/app/cli/commands/vc/revoke.py @@ -122,9 +122,7 @@ def revokeDo(self, tymth, tock=0.0): aserder = serdering.SerderKERI(raw=bytes(anc)) self.registrar.revoke(creder, rserder, aserder) - senderHab = self.hab if isinstance(self.hab, GroupHab): - senderHab = self.hab.mhab smids = self.hab.db.signingMembers(pre=self.hab.pre) smids.remove(self.hab.mhab.pre) @@ -139,8 +137,13 @@ def revokeDo(self, tymth, tock=0.0): while not self.registrar.complete(creder.said, sn=1): yield self.tock - if self.hab.witnesser() and 'i' in creder.attrib: - recp = creder.attrib['i'] + recps = [creder.attrib['i']] if 'i' in creder.attrib else [] + if self.send is not None: + recps.extend(self.send) + + senderHab = self.hab.mhab if isinstance(self.hab, GroupHab) else self.hab + + if len(recps) > 0: msgs = [] for msg in self.hby.db.clonePreIter(pre=creder.issuer): serder = serdering.SerderKERI(raw=msg) @@ -151,12 +154,21 @@ def revokeDo(self, tymth, tock=0.0): atc = msg[serder.size:] msgs.append((serder, atc)) - for (serder, atc) in msgs: - self.postman.send(src=senderHab.pre, dest=recp, topic="credential", serder=serder, - attachment=atc) - - last = msgs[-1][0] - while not self.postman.sent(said=last.said): + sent = 0 + for send in recps: + if send in self.hby.kevers: + recp = send + else: + recp = self.org.find("alias", send) + if len(recp) != 1: + raise ValueError(f"invalid recipient {send}") + recp = recp[0]['id'] + for (serder, atc) in msgs: + self.postman.send(src=senderHab.pre, dest=recp, topic="credential", serder=serder, + attachment=atc) + sent += 1 + + while not len(self.postman.cues) == sent: yield self.tock except kering.ValidationError as ex: From 94c8c8d021e73032b42a29d30635f18c7a332833 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Tue, 26 Mar 2024 18:42:13 -0700 Subject: [PATCH 07/61] Version Bump Signed-off-by: pfeairheller --- Makefile | 6 ++++-- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 0befb65e3..63fb1ec2b 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.8 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.9 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.9-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.8 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.9 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.9-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 0b432d6fc..c882a1740 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.8` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.9` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index d3b4c467a..3e664cb50 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.8', # also change in src/keri/__init__.py + version='1.1.9', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 31d78b34b..ccfbcc09a 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.8' # also change in setup.py +__version__ = '1.1.9' # also change in setup.py From da94906f1f45f59893f76eaa36bf912d00fb6b16 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 2 Apr 2024 14:21:02 -0400 Subject: [PATCH 08/61] adds escrow clean up to migrate (#733) Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/migrate.py | 9 +++++++++ src/keri/db/basing.py | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/keri/app/cli/commands/migrate.py b/src/keri/app/cli/commands/migrate.py index 0f4035f78..2116ee267 100644 --- a/src/keri/app/cli/commands/migrate.py +++ b/src/keri/app/cli/commands/migrate.py @@ -125,6 +125,15 @@ def migrate(tymth, tock=0.0, **opts): migrateKeys(hby.db) + # clear escrows + print("clearing escrows") + hby.db.gpwe.trim() + hby.db.gdee.trim() + hby.db.dpwe.trim() + hby.db.gpse.trim() + hby.db.epse.trim() + hby.db.dune.trim() + except ConfigurationError: print(f"identifier prefix for {name} does not exist, incept must be run first", ) return -1 diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index d4263fc91..127df822b 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -883,7 +883,7 @@ def reopen(self, **kwa): self.ends = koming.Komer(db=self, subkey='ends.', schema=EndpointRecord, ) - # service endpont locations keyed by eid.scheme (endpoint identifier) + # service endpoint locations keyed by eid.scheme (endpoint identifier) # data extracted from reply loc self.locs = koming.Komer(db=self, subkey='locs.', @@ -1015,12 +1015,14 @@ def reopen(self, **kwa): # Global settings for the Habery environment self.hbys = subing.Suber(db=self, subkey='hbys.') + # Signed contact data, keys by prefix self.cons = subing.Suber(db=self, subkey="cons.") # Transferable signatures on contact data self.ccigs = subing.CesrSuber(db=self, subkey='ccigs.', klas=coring.Cigar) + # Chunked image data for contact information for remote identifiers self.imgs = self.env.open_db(key=b'imgs.') From 636774fa18a6cd1f78986788a1cc931518c5e805 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 2 Apr 2024 15:24:45 -0400 Subject: [PATCH 09/61] version 1.1.10 Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 63fb1ec2b..6c1cbcd0c 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.9 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.9-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.10 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.10-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.9 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.9-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.10 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.10-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index c882a1740..22afbc1d1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.9` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.10` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 3e664cb50..13fd2fc2a 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.9', # also change in src/keri/__init__.py + version='1.1.10', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index ccfbcc09a..6430d86e9 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.9' # also change in setup.py +__version__ = '1.1.10' # also change in setup.py From 258726d1d8ec816547f5f3383ef964c2b2c8cc44 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Thu, 4 Apr 2024 14:16:55 -0700 Subject: [PATCH 10/61] Update to contact list to account for non-backward compatible changes and to multisig update to account for KeyStateRecord changes. Signed-off-by: pfeairheller --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- src/keri/app/cli/commands/contacts/list.py | 11 +++++++++-- src/keri/app/cli/commands/multisig/update.py | 4 ++-- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 6c1cbcd0c..5b04239c9 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.10 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.10-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.11 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.11-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.10 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.10-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.11 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.11-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 22afbc1d1..7563fb4ef 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.10` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.11` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 13fd2fc2a..305b70da9 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.10', # also change in src/keri/__init__.py + version='1.1.11', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 6430d86e9..dd3a6e142 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.10' # also change in setup.py +__version__ = '1.1.11' # also change in setup.py diff --git a/src/keri/app/cli/commands/contacts/list.py b/src/keri/app/cli/commands/contacts/list.py index fa7527d79..1ba574483 100644 --- a/src/keri/app/cli/commands/contacts/list.py +++ b/src/keri/app/cli/commands/contacts/list.py @@ -9,6 +9,7 @@ from hio import help from hio.base import doing +from keri import kering from keri.app import connecting from keri.app.cli.common import existing @@ -53,8 +54,14 @@ def list(tymth, tock=0.0, **opts): challenges = [] for said in valid: - exn = hby.db.exns.get(keys=(said,)) - challenges.append(dict(dt=exn.ked['dt'], words=exn.ked['a']['words'])) + try: + exn = hby.db.exns.get(keys=(said,)) + except kering.ValidationError: + val = hby.db.getVal(db=hby.db.exns.sdb, key=hby.db.exns._tokey((said,))) + d = json.loads(bytes(val).decode("utf-8")) + challenges.append(dict(dt=d['dt'], words=d['a']['words'])) + else: + challenges.append(dict(dt=exn.ked['dt'], words=exn.ked['a']['words'])) c["challenges"] = challenges diff --git a/src/keri/app/cli/commands/multisig/update.py b/src/keri/app/cli/commands/multisig/update.py index 5d7284ea8..4ef7d19fc 100644 --- a/src/keri/app/cli/commands/multisig/update.py +++ b/src/keri/app/cli/commands/multisig/update.py @@ -119,8 +119,8 @@ def updateDo(self, tymth, tock=0.0, **opts): print("") witstate = self.hab.db.ksns.get((saider.qb64,)) - if witstate.sn != self.sn and witstate.ked['d'] != self.said: - print(f"Witness state ({witstate.sn}, {witstate.ked['d']}) does not match requested state.") + if int(witstate.s, 16) != self.sn and witstate.d != self.said: + print(f"Witness state ({witstate.s}, {witstate.d}) does not match requested state.") self.remove(self.toRemove) return From 03367edfe9856b342bbc68f3a86cf49e624cdae9 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Tue, 9 Apr 2024 19:58:36 -0400 Subject: [PATCH 11/61] process only saved credentials during migration (#749) - update migrate command to process only saved credentials - while migrating keys, skip missing events Signed-off-by: arshdeep singh --- src/keri/app/cli/commands/migrate.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/keri/app/cli/commands/migrate.py b/src/keri/app/cli/commands/migrate.py index 2116ee267..775f957b9 100644 --- a/src/keri/app/cli/commands/migrate.py +++ b/src/keri/app/cli/commands/migrate.py @@ -114,7 +114,7 @@ def migrate(tymth, tock=0.0, **opts): # ksr = stateFromKever(kever) rgy.states.pin(sad['i'], val=rsr) - for (said,), _ in rgy.creds.getItemIter(): + for (said,), _ in rgy.saved.getItemIter(): snkey = dbing.snKey(said, 0) dig = rgy.getTel(key=snkey) @@ -151,7 +151,8 @@ def migrateKeys(db): for pre, fn, dig in db.getFelItemAllPreIter(key=b''): dgkey = dbing.dgKey(pre, dig) # get message if not (raw := db.getEvt(key=dgkey)): - raise kering.MissingEntryError("Missing event for dig={}.".format(dig)) + print(f"Migrate keys: missing event for dig={dig}, skipped.") + continue serder = serdering.SerderKERI(raw=bytes(raw)) val = (coring.Prefixer(qb64b=serder.preb), coring.Seqner(sn=serder.sn)) verfers = serder.verfers or [] From e770118c144ab68b53a6fc16a64598b4f8907ed2 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Wed, 10 Apr 2024 07:43:51 -0700 Subject: [PATCH 12/61] Version bump --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 5b04239c9..fb53215cb 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.11 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.11-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.12 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.12-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.11 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.11-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.12 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.12-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 7563fb4ef..675894b88 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.11` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.12` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 305b70da9..ff9a41032 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.11', # also change in src/keri/__init__.py + version='1.1.12', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index dd3a6e142..6d16b3fcb 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.11' # also change in setup.py +__version__ = '1.1.12' # also change in setup.py From 6d8ad2183dc3a6ff668fdff2a85cd8e39798f40b Mon Sep 17 00:00:00 2001 From: Philip Feairheller Date: Thu, 25 Apr 2024 12:38:46 -0700 Subject: [PATCH 13/61] Fix OOBI resolution (#766) * Fix OOBI resolution to account for knowing about a delegated AID without having the delegation approval. Added test. Closes #762 Signed-off-by: pfeairheller * Testing older mac test running on GitHub Signed-off-by: pfeairheller --------- Signed-off-by: pfeairheller --- .github/workflows/python-app-ci.yml | 2 +- src/keri/db/basing.py | 3 ++ src/keri/end/ending.py | 4 +++ tests/end/test_ending.py | 43 +++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-app-ci.yml b/.github/workflows/python-app-ci.yml index 2df15d859..4bfde6420 100644 --- a/.github/workflows/python-app-ci.yml +++ b/.github/workflows/python-app-ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ macos-latest, ubuntu-latest ] + os: [ macos-13, ubuntu-latest ] steps: - uses: actions/checkout@v3 diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index 127df822b..c652646a8 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1261,6 +1261,9 @@ def cloneEvtMsg(self, pre, fn, dig): atc.extend(coring.Counter(code=coring.CtrDex.SealSourceCouples, count=1).qb64b) atc.extend(couple) + elif self.kevers[pre].delegated: + if coring.SerderKERI(raw=raw).estive: + raise kering.MissingEntryError("Missing delegator anchor seal for dig={}.".format(dig)) # add trans receipts quadruples to attachments if quads := self.getVrcs(key=dgkey): diff --git a/src/keri/end/ending.py b/src/keri/end/ending.py index 9e65ab7f0..4746e0bf6 100644 --- a/src/keri/end/ending.py +++ b/src/keri/end/ending.py @@ -577,6 +577,10 @@ def on_get(self, req, rep, aid=None, role=None, eid=None): rep.status = falcon.HTTP_NOT_FOUND return + if kever.delegated and kever.delegator not in self.hby.kevers: + rep.status = falcon.HTTP_NOT_FOUND + return + owits = oset(kever.wits) if kever.prefixer.qb64 in self.hby.prefixes: # One of our identifiers hab = self.hby.habs[kever.prefixer.qb64] diff --git a/tests/end/test_ending.py b/tests/end/test_ending.py index c08a601fe..9b62a0b36 100644 --- a/tests/end/test_ending.py +++ b/tests/end/test_ending.py @@ -434,6 +434,49 @@ def test_get_oobi(): assert serder.ked['t'] == coring.Ilks.icp assert serder.ked['i'] == "EOaICQwhOy3wMwecjAuHQTbv_Cmuu1azTMnHi4QtUmEU" + delname = "delegator" + with habbing.openHby(name=name, base=base, salt=salt) as hby, \ + habbing.openHby(name=delname, base=base, salt=salt) as delhby: + delhab = delhby.makeHab(name=delname) + hab = hby.makeHab(name=name, delpre=delhab.pre) + + assert hab.pre == "EPERMS4wKU7ejhCdhI2qQR8snEx1cislR9C9bSEs0kS5" + assert hab.kever.delegator == delhab.pre + + msgs.extend(hab.makeEndRole(eid=hab.pre, + role=kering.Roles.controller, + stamp=help.nowIso8601())) + + msgs.extend(hab.makeLocScheme(url='http://127.0.0.1:5555', + scheme=kering.Schemes.http, + stamp=help.nowIso8601())) + hab.psr.parse(ims=msgs) + + # must do it here to inject into Falcon endpoint resource instances + tymist = tyming.Tymist(tyme=0.0) + + app = falcon.App() # falcon.App instances are callable WSGI apps + ending.loadEnds(app, tymth=tymist.tymen(), hby=hby, default=hab.pre) + + client = testing.TestClient(app=app) + + # This should fail with 404 because we haven't been approved yet so we don't exist + rep = client.simulate_get('/oobi', ) + assert rep.status == falcon.HTTP_NOT_FOUND + + # Approve the delegation manually + delhab.interact(data=[dict(i=hab.pre, s="0", d=hab.pre)]) + for msg in delhab.db.clonePreIter(pre=delhab.pre, fn=0): + hab.psr.parse(ims=msg) + + rep = client.simulate_get('/oobi', ) + assert rep.status == falcon.HTTP_OK + + # We'll get the delegator first + serder = serdering.SerderKERI(raw=rep.text.encode("utf-8")) + assert serder.ked['t'] == coring.Ilks.icp + assert serder.ked['i'] == "EKL3to0Q059vtxKi7wWmaNFJ3NKE1nQsOPasRXqPzpjS" + """Done Test""" From fa919706cadd2d229b56a4a0d43fac57fbba4aa2 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Thu, 25 Apr 2024 12:55:48 -0700 Subject: [PATCH 14/61] Version bump Signed-off-by: pfeairheller --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fb53215cb..fa517f198 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.12 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.12-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.13 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.13-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.12 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.12-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.13 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.13-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 675894b88..f0431ad47 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.12` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.13` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index ff9a41032..b6e9c91d3 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.12', # also change in src/keri/__init__.py + version='1.1.13', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 6d16b3fcb..dbd38b7d5 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.12' # also change in setup.py +__version__ = '1.1.13' # also change in setup.py From 08e5730845abf45cd9c7ed9d3eeaab581c2f8a95 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 9 May 2024 11:00:40 -0400 Subject: [PATCH 15/61] Feat/no bran (#781) * removes bran from GroupMultisigRotate constructor inplace of an existing Habery Signed-off-by: Kevin Griffin * removes bran Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/multisig/rotate.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/keri/app/cli/commands/multisig/rotate.py b/src/keri/app/cli/commands/multisig/rotate.py index fba05fd64..c6c52462b 100644 --- a/src/keri/app/cli/commands/multisig/rotate.py +++ b/src/keri/app/cli/commands/multisig/rotate.py @@ -53,9 +53,9 @@ def rotateGroupIdentifier(args): """ data = config.parseData(args.data) if args.data is not None else None - - rotDoer = GroupMultisigRotate(name=args.name, base=args.base, alias=args.alias, smids=args.smids, rmids=args.rmids, - bran=args.bran, wits=args.witnesses, cuts=args.cuts, adds=args.witness_add, + hby = existing.setupHby(name=args.name, base=args.base, bran=args.bran) + rotDoer = GroupMultisigRotate(hby=hby, alias=args.alias, smids=args.smids, rmids=args.rmids, + wits=args.witnesses, cuts=args.cuts, adds=args.witness_add, isith=args.isith, nsith=args.nsith, toad=args.toad, data=data) doers = [rotDoer] @@ -70,7 +70,7 @@ class GroupMultisigRotate(doing.DoDoer): """ - def __init__(self, name, base, bran, alias, smids=None, rmids=None, isith=None, nsith=None, + def __init__(self, hby, alias, smids=None, rmids=None, isith=None, nsith=None, toad=None, wits=None, cuts=None, adds=None, data: list = None): self.alias = alias @@ -80,12 +80,12 @@ def __init__(self, name, base, bran, alias, smids=None, rmids=None, isith=None, self.smids = smids self.rmids = rmids self.data = data + self.hby = hby self.wits = wits if wits is not None else [] self.cuts = cuts if cuts is not None else [] self.adds = adds if adds is not None else [] - self.hby = existing.setupHby(name=name, base=base, bran=bran) self.hbyDoer = habbing.HaberyDoer(habery=self.hby) # setup doer notifier = Notifier(self.hby) mux = grouping.Multiplexor(self.hby, notifier=notifier) From 652ab0933f9971f10e43f2dbaa75666ad6ed6f1c Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 9 May 2024 11:40:03 -0400 Subject: [PATCH 16/61] v1.1.14 Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index fa517f198..2cd8fedda 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.13 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.13-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.14 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.14-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.13 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.13-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.14 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.14-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index f0431ad47..8a822defa 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.13` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.14` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index b6e9c91d3..1888e20bd 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.13', # also change in src/keri/__init__.py + version='1.1.14', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index dbd38b7d5..c6de5e617 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.13' # also change in setup.py +__version__ = '1.1.14' # also change in setup.py From 77b1d43da378766b2a4da8128f3dd34eeffa79db Mon Sep 17 00:00:00 2001 From: Kent Bull <65027257+kentbull@users.noreply.github.com> Date: Tue, 14 May 2024 17:07:56 -0600 Subject: [PATCH 17/61] feat: multisig join --group arg (#782) * feat: multisig join --alias arg * fix: alias->group if auto True else default --- src/keri/app/cli/commands/multisig/join.py | 59 +++++++++++++--------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/keri/app/cli/commands/multisig/join.py b/src/keri/app/cli/commands/multisig/join.py index 94b1e058e..4617022cd 100644 --- a/src/keri/app/cli/commands/multisig/join.py +++ b/src/keri/app/cli/commands/multisig/join.py @@ -21,47 +21,52 @@ logger = help.ogler.getLogger() parser = argparse.ArgumentParser(description='Join group multisig inception, rotation or interaction event.') -parser.set_defaults(handler=lambda args: confirm(args)) +parser.set_defaults(handler=lambda args: join(args)) parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', required=False, default="") +parser.add_argument('--group', '-a', help='human-readable name for the multisig group identifier prefix', required=False, default=None) parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran parser.add_argument("--auto", "-Y", help="auto approve any delegation request non-interactively", action="store_true") -def confirm(args): - """ Wait for and provide interactive confirmation of group multisig inception, rotation or interaction events +def join(args): + """ Wait for and provide interactive confirmation of group multisig inception, rotation or interaction events Parameters: - args(Namespace): parsed arguements namespace object + args(Namespace): parsed arguments namespace object """ name = args.name base = args.base bran = args.bran auto = args.auto + group = args.group - confirmDoer = ConfirmDoer(name=name, base=base, bran=bran, auto=auto) + joinDoer = JoinDoer(name=name, base=base, bran=bran, group=group, auto=auto) - doers = [confirmDoer] + doers = [joinDoer] return doers -class ConfirmDoer(doing.DoDoer): - """ Doist doer capable of polling for group multisig events and prompting user for action +class JoinDoer(doing.DoDoer): + """ Doist doer capable of polling for group multisig events and prompting user for action """ - def __init__(self, name, base, bran, auto=False): + def __init__(self, name, base, bran, group, auto=False): """ Create doer for polling for group multisig events and either approve automatically or prompt user Parameters: name (str): database environment name base (str): database directory prefix bran (str): passcode to unlock keystore - + group (str): human-readable name for the multisig identifier prefix + auto (bool): non-interactively auto approve any inception, rotation, interaction, or other event + while using the default group of "default-group" """ + self.group = group self.hby = existing.setupHby(name=name, base=base, bran=bran) self.rgy = credentialing.Regery(hby=self.hby, name=name, base=base) self.hbyDoer = habbing.HaberyDoer(habery=self.hby) # setup doer @@ -88,11 +93,11 @@ def __init__(self, name, base, bran, auto=False): doers = [self.hbyDoer, self.witq, self.mbx, self.counselor, self.registrar, self.credentialer, self.postman] self.toRemove = list(doers) - doers.extend([doing.doify(self.confirmDo)]) + doers.extend([doing.doify(self.joinDo)]) self.auto = auto - super(ConfirmDoer, self).__init__(doers=doers) + super(JoinDoer, self).__init__(doers=doers) - def confirmDo(self, tymth, tock=0.0): + def joinDo(self, tymth, tock=0.0): """ Parameters: tymth (function): injected function wrapper closure returned by .tymen() of @@ -146,7 +151,7 @@ def confirmDo(self, tymth, tock=0.0): self.remove(self.toRemove) def incept(self, attrs): - """ Incept group multisig + """ Join a group multisig inception event """ said = attrs["d"] @@ -196,17 +201,20 @@ def incept(self, attrs): if approve: if self.auto: - alias = "test alias" + if self.group is None: + group = "default-group" + else: + group = self.group else: while True: - alias = input(f"\nEnter alias for new AID: ") - if self.hby.habByName(alias) is not None: - print(f"AID alias {alias} is already in use, please try again") + group = input(f"\nEnter group name for new AID: ") + if self.hby.habByName(group) is not None: + print(f"AID group name {group} is already in use, please try again") else: break try: - ghab = self.hby.makeGroupHab(group=alias, mhab=mhab, + ghab = self.hby.makeGroupHab(group=group, mhab=mhab, smids=smids, rmids=rmids, **inits) except ValueError as e: return False @@ -393,16 +401,19 @@ def rotate(self, attrs): ghab = self.hby.habs[pre] else: if self.auto: - alias = "test alias" + if self.group is None: + group = "default-group" + else: + group = self.group else: while True: - alias = input(f"\nEnter alias for new AID: ") - if self.hby.habByName(alias) is not None: - print(f"AID alias {alias} is already in use, please try again") + group = input(f"\nEnter group name for new AID: ") + if self.hby.habByName(group) is not None: + print(f"AID group name {group} is already in use, please try again") else: break - ghab = self.hby.joinGroupHab(pre, group=alias, mhab=mhab, smids=smids, rmids=rmids) + ghab = self.hby.joinGroupHab(pre, group=group, mhab=mhab, smids=smids, rmids=rmids) try: ghab.rotate(serder=orot) From f2cf0f27629df46ae26085a77404e270f073b14f Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Fri, 31 May 2024 11:26:03 -0400 Subject: [PATCH 18/61] fixes some usages of coring.Serder to use serdering.SerderKERI (#788) * fixes some usages of coring.Serder to use serdering.SerderKERI Signed-off-by: Kevin Griffin * fixes import Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/multisig/notice.py | 4 ++-- src/keri/db/basing.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/keri/app/cli/commands/multisig/notice.py b/src/keri/app/cli/commands/multisig/notice.py index a442eab0c..70902b2fb 100644 --- a/src/keri/app/cli/commands/multisig/notice.py +++ b/src/keri/app/cli/commands/multisig/notice.py @@ -11,8 +11,8 @@ from keri.app import habbing, forwarding, grouping from keri.app.cli.common import existing -from keri.core import coring from keri.core.coring import Ilks +from keri.core import serdering logger = help.ogler.getLogger() @@ -86,7 +86,7 @@ def noticeDo(self, tymth, tock=0.0): (smids, rmids) = hab.members() serder = hab.kever.serder rot = hab.makeOwnEvent(sn=hab.kever.sn) - eserder = coring.Serder(raw=rot) + eserder = serdering.SerderKERI(raw=rot) del rot[:eserder.size] ilk = serder.ked['t'] diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index c652646a8..cd2193062 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1262,7 +1262,7 @@ def cloneEvtMsg(self, pre, fn, dig): count=1).qb64b) atc.extend(couple) elif self.kevers[pre].delegated: - if coring.SerderKERI(raw=raw).estive: + if serdering.SerderKERI(raw=raw).estive: raise kering.MissingEntryError("Missing delegator anchor seal for dig={}.".format(dig)) # add trans receipts quadruples to attachments From 6c8e86bc11eddeaeda331ebbb02cba737727ca37 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Fri, 31 May 2024 14:06:35 -0400 Subject: [PATCH 19/61] 1.1.15 bump Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 2cd8fedda..be762a272 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.14 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.14-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.15 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.15-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.14 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.14-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.15 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.15-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 8a822defa..3ca1486ac 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.14` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.15` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 1888e20bd..31eefb692 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.14', # also change in src/keri/__init__.py + version='1.1.15', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index c6de5e617..b50cdd361 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.14' # also change in setup.py +__version__ = '1.1.15' # also change in setup.py From 9f433178a1122a27fdf7b0cace271e97047d26ef Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 3 Jun 2024 07:25:41 -0400 Subject: [PATCH 20/61] updates dockerfile to new alpine (#792) * updates dockerfile to new alpine Signed-off-by: Kevin Griffin * updates dockerfile to new alpine Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- images/keripy.dockerfile | 41 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/images/keripy.dockerfile b/images/keripy.dockerfile index ca12837fc..3c2a5924b 100644 --- a/images/keripy.dockerfile +++ b/images/keripy.dockerfile @@ -1,18 +1,21 @@ -# Builder layer -FROM python:3.10-alpine as builder +ARG BASE=python:3.10.14-alpine3.20 -# Install compilation dependencies -RUN apk --no-cache add \ - bash \ +FROM ${BASE} as builder + +RUN apk add --no-cache bash + +SHELL ["/bin/bash", "-c"] + +RUN apk add --no-cache \ + curl \ + build-base \ alpine-sdk \ libffi-dev \ libsodium \ - libsodium-dev - -SHELL ["/bin/bash", "-c"] + libsodium-dev -# Setup Rust for blake3 dependency build -RUN curl https://sh.rustup.rs -sSf | bash -s -- -y +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/root/.cargo/bin:${PATH}" WORKDIR /keripy @@ -20,19 +23,16 @@ RUN python -m venv venv ENV PATH=/keripy/venv/bin:${PATH} -RUN pip install --upgrade pip && \ - mkdir /keripy/src +RUN pip install --upgrade pip +RUN mkdir /keripy/src -# Copy Python dependency files in COPY requirements.txt setup.py ./ -# Set up Rust environment and install Python dependencies -# Must source the Cargo environment for the blake3 library to see -# the Rust intallation during requirements install -RUN . ${HOME}/.cargo/env && \ - pip install -r requirements.txt + +RUN . ${HOME}/.cargo/env +RUN pip install -r requirements.txt # Runtime layer -FROM python:3.10.13-alpine3.18 +FROM ${BASE} RUN apk --no-cache add \ bash \ @@ -44,7 +44,6 @@ WORKDIR /keripy COPY --from=builder /keripy /keripy COPY src/ src/ -ENV PATH=/keripy/venv/bin:${PATH} - +ENV PATH="/keripy/venv/bin:${PATH}" ENTRYPOINT [ "kli" ] From 1d2e76662a0c28cf5f3968896751ad33dc2d773b Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 3 Jun 2024 17:46:21 -0400 Subject: [PATCH 21/61] adds bytes cast (#795) * fix vc list from a delegated aid Signed-off-by: Kevin Griffin * Revert "fix vc list from a delegated aid" This reverts commit 139b7d5b6f340ba93ffb8e20e24e623b1da55f7b. * fixes vc list for delegated aids Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- src/keri/db/basing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index cd2193062..0f808a8d4 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1262,7 +1262,7 @@ def cloneEvtMsg(self, pre, fn, dig): count=1).qb64b) atc.extend(couple) elif self.kevers[pre].delegated: - if serdering.SerderKERI(raw=raw).estive: + if serdering.SerderKERI(raw=bytes(raw)).estive: raise kering.MissingEntryError("Missing delegator anchor seal for dig={}.".format(dig)) # add trans receipts quadruples to attachments From 5b626abb0eb31dac6c9c11d6b0a08b4fae5d284d Mon Sep 17 00:00:00 2001 From: Kent Bull <65027257+kentbull@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:13:52 -0600 Subject: [PATCH 22/61] fix: correct short arg for --group from -a to -g (#801) --- src/keri/app/cli/commands/multisig/join.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keri/app/cli/commands/multisig/join.py b/src/keri/app/cli/commands/multisig/join.py index 4617022cd..ea4132aa2 100644 --- a/src/keri/app/cli/commands/multisig/join.py +++ b/src/keri/app/cli/commands/multisig/join.py @@ -25,7 +25,7 @@ parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', required=False, default="") -parser.add_argument('--group', '-a', help='human-readable name for the multisig group identifier prefix', required=False, default=None) +parser.add_argument('--group', '-g', help='human-readable name for the multisig group identifier prefix', required=False, default=None) parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran parser.add_argument("--auto", "-Y", help="auto approve any delegation request non-interactively", action="store_true") From 89317bd5be99fd08eec78c8c96541f56170d68ee Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 4 Jul 2024 08:53:19 -0400 Subject: [PATCH 23/61] fixes end role check - bump to v1.1.16 Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index be762a272..9623dfc3d 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.15 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.15-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.16 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.16-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.15 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.15-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.16 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.16-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 3ca1486ac..fd3f602d6 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.15` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.16` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 31eefb692..fc43547f4 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.15', # also change in src/keri/__init__.py + version='1.1.16', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index b50cdd361..e0aa3503d 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.15' # also change in setup.py +__version__ = '1.1.16' # also change in setup.py From d62ce52ca2fd00ef80fc312395eebd0bfc0b4b94 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 4 Jul 2024 13:02:40 -0400 Subject: [PATCH 24/61] fixes end role check - bump to v1.1.16 Signed-off-by: Kevin Griffin --- src/keri/core/eventing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index 94a4e7177..54ab3b72f 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -3780,6 +3780,8 @@ def processReplyEndRole(self, *, serder, saider, route, aid = cid # authorizing attribution id keys = (aid, role, eid) osaider = self.db.eans.get(keys=keys) # get old said if any + if osaider is not None and osaider.qb64b == saider.qb64b: # check idempotent + osaider = None # BADA Logic accepted = self.rvy.acceptReply(serder=serder, saider=saider, route=route, aid=aid, osaider=osaider, cigars=cigars, From 64e712ec510d74064ceef1d8a7a6a0e18cb364b8 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Fri, 5 Jul 2024 18:33:05 -0400 Subject: [PATCH 25/61] v1.1.17 Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9623dfc3d..5ce1a3878 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.16 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.16-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.17 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.17-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.16 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.16-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.17 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.17-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index fd3f602d6..57da66050 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.16` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.17` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index fc43547f4..becee6066 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.16', # also change in src/keri/__init__.py + version='1.1.17', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index e0aa3503d..1aaad6002 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.16' # also change in setup.py +__version__ = '1.1.17' # also change in setup.py From 9a4ed6a7fe6f8f112eb796018dbcc3d68be82522 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 25 Jul 2024 11:09:20 -0400 Subject: [PATCH 26/61] updates Hio version (#823) * updates Hio version Signed-off-by: Kevin Griffin * updates python version and dependencies Signed-off-by: Kevin Griffin * updates ci python version Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- .github/workflows/python-app-ci.yml | 12 ++++---- images/keripy.dockerfile | 2 +- setup.py | 44 ++++++++++++++--------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/python-app-ci.yml b/.github/workflows/python-app-ci.yml index 4bfde6420..145adba45 100644 --- a/.github/workflows/python-app-ci.yml +++ b/.github/workflows/python-app-ci.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up Python 3.10.4 + - name: Set up Python 3.12.2 uses: actions/setup-python@v2 with: - python-version: 3.10.4 + python-version: 3.12.2 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -47,10 +47,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Python 3.10.4 + - name: Set up Python 3.12.2 uses: actions/setup-python@v2 with: - python-version: 3.10.4 + python-version: 3.12.2 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -68,10 +68,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Python 3.10.4 + - name: Set up Python 3.12.2 uses: actions/setup-python@v2 with: - python-version: 3.10.4 + python-version: 3.12.2 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/images/keripy.dockerfile b/images/keripy.dockerfile index 3c2a5924b..4e553b87c 100644 --- a/images/keripy.dockerfile +++ b/images/keripy.dockerfile @@ -1,4 +1,4 @@ -ARG BASE=python:3.10.14-alpine3.20 +ARG BASE=python:3.12.2-alpine3.19 FROM ${BASE} as builder diff --git a/setup.py b/setup.py index becee6066..15f436d48 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ 'Operating System :: Unix', 'Operating System :: POSIX', 'Operating System :: Microsoft :: Windows', - 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', # uncomment if you test on these interpreters: # 'Programming Language :: Python :: Implementation :: PyPy', @@ -68,32 +68,32 @@ keywords=[ # eg: 'keyword1', 'keyword2', 'keyword3', ], - python_requires='>=3.10.4', + python_requires='>=3.12.2', install_requires=[ - 'lmdb>=1.3.0', - 'pysodium>=0.7.12', - 'blake3>=0.3.1', - 'msgpack>=1.0.4', - 'cbor2>=5.4.3', - 'multidict>=6.0.2', - 'ordered-set>=4.1.0', - 'hio>=0.6.9', - 'multicommand>=1.0.0', - 'jsonschema>=4.17.0', - 'falcon>=3.1.0', - 'hjson>=3.0.2', - 'PyYaml>=6.0', - 'apispec>=6.0.0', - 'mnemonic>=0.20', - 'PrettyTable>=3.5.0', - 'http_sfv>=0.9.8', - 'cryptography>=39.0.2' + 'lmdb>=1.4.1', + 'pysodium>=0.7.17', + 'blake3>=0.4.1', + 'msgpack>=1.0.8', + 'cbor2>=5.6.2', + 'multidict>=6.0.5', + 'ordered-set>=4.1.0', + 'hio>=0.6.14', + 'multicommand>=1.0.0', + 'jsonschema>=4.21.1', + 'falcon>=3.1.3', + 'hjson>=3.1.0', + 'PyYaml>=6.0.1', + 'apispec>=6.6.0', + 'mnemonic>=0.21', + 'PrettyTable>=3.10.0', + 'http_sfv>=0.9.9', + 'cryptography>=42.0.5' ], extras_require={ }, tests_require=[ - 'coverage>=6.5.0', - 'pytest>=7.2.0', + 'coverage>=7.4.4', + 'pytest>=8.1.1', 'pytest-shell>=0.3.2' ], setup_requires=[ From 9061ef9d3d0a1f129477d4075047dbb7baf648f3 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Fri, 26 Jul 2024 12:34:53 -0400 Subject: [PATCH 27/61] bump to 1.1.18 Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 5ce1a3878..f22f2a226 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.17 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.17-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.18 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.18-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.17 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.17-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.18 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.18-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 57da66050..8936cf55c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.17` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.18` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 15f436d48..e29a9fd29 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.17', # also change in src/keri/__init__.py + version='1.1.18', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 1aaad6002..b33bc909f 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.17' # also change in setup.py +__version__ = '1.1.18' # also change in setup.py From c2eef91ad5d3e6992b323eb7a067eca809cb3b13 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Fri, 4 Oct 2024 12:47:15 -0600 Subject: [PATCH 28/61] feat: update smids and rmids on rotate (#857) This updates the database HabitatRecord smids and rmids properties when a group rotation happens. Signed-off-by: Kent Bull --- src/keri/app/cli/commands/multisig/join.py | 2 +- src/keri/app/cli/commands/multisig/rotate.py | 2 +- src/keri/app/habbing.py | 39 ++++--- tests/app/test_grouping.py | 110 +++++++++++++++++-- 4 files changed, 128 insertions(+), 25 deletions(-) diff --git a/src/keri/app/cli/commands/multisig/join.py b/src/keri/app/cli/commands/multisig/join.py index ea4132aa2..b85db6b75 100644 --- a/src/keri/app/cli/commands/multisig/join.py +++ b/src/keri/app/cli/commands/multisig/join.py @@ -416,7 +416,7 @@ def rotate(self, attrs): ghab = self.hby.joinGroupHab(pre, group=group, mhab=mhab, smids=smids, rmids=rmids) try: - ghab.rotate(serder=orot) + ghab.rotate(serder=orot, smids=smids, rmids=rmids) except ValueError: return False diff --git a/src/keri/app/cli/commands/multisig/rotate.py b/src/keri/app/cli/commands/multisig/rotate.py index c6c52462b..126534ec2 100644 --- a/src/keri/app/cli/commands/multisig/rotate.py +++ b/src/keri/app/cli/commands/multisig/rotate.py @@ -203,7 +203,7 @@ def rotateDo(self, tymth, tock=0.0, **opts): prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn+1) - rot = ghab.rotate(isith=self.isith, nsith=self.nsith, + rot = ghab.rotate(smids=smids, rmids=rmids, isith=self.isith, nsith=self.nsith, toad=self.toad, cuts=list(self.cuts), adds=list(self.adds), data=self.data, verfers=merfers, digers=migers) diff --git a/src/keri/app/habbing.py b/src/keri/app/habbing.py index 965f64f26..2eed0d94f 100644 --- a/src/keri/app/habbing.py +++ b/src/keri/app/habbing.py @@ -330,7 +330,7 @@ def loadHabs(self): if habord.mid and not habord.sid: hab = GroupHab(ks=self.ks, db=self.db, cf=self.cf, mgr=self.mgr, rtr=self.rtr, rvy=self.rvy, kvy=self.kvy, psr=self.psr, - name=name, pre=pre, temp=self.temp, smids=habord.smids) + name=name, pre=pre, temp=self.temp, smids=habord.smids, rmids=habord.rmids) groups.append(habord) elif habord.sid and not habord.mid: hab = SignifyHab(ks=self.ks, db=self.db, cf=self.cf, mgr=self.mgr, @@ -2736,24 +2736,34 @@ def make(self, *, code=coring.MtrDex.Blake3_256, transferable=True, isith=None, self.inited = True - def rotate(self, serder=None, **kwargs): + def rotate(self, serder=None, smids=None, rmids=None, **kwargs): + + if (habord := self.db.habs.get(keys=(self.name,))) is None: + raise kering.ValidationError(f"Missing HabitatRecord for name={self.name}") if serder is None: - return super(GroupHab, self).rotate(**kwargs) + msg = super(GroupHab, self).rotate(**kwargs) + else: - # sign handles group hab with .mhab case - sigers = self.sign(ser=serder.raw, verfers=serder.verfers, rotated=True) + # sign handles group hab with .mhab case + sigers = self.sign(ser=serder.raw, verfers=serder.verfers, rotated=True) - # update own key event verifier state - msg = eventing.messagize(serder, sigers=sigers) + # update own key event verifier state + msg = eventing.messagize(serder, sigers=sigers) - try: - self.kvy.processEvent(serder=serder, sigers=sigers) - except MissingSignatureError: - pass - except Exception as ex: - raise kering.ValidationError("Improper Habitat rotation for " - "pre={self.pre}.") from ex + try: + self.kvy.processEvent(serder=serder, sigers=sigers) + except MissingSignatureError: + pass + except Exception as ex: + raise kering.ValidationError("Improper Habitat rotation for " + "pre={self.pre}.") from ex + + self.smids = smids + self.rmids = rmids + habord.smids = smids + habord.rmids = rmids + self.db.habs.pin(keys=(self.name,), val=habord) return msg @@ -2870,7 +2880,6 @@ def query(self, pre, src, query=None, **kwa): return self.mhab.endorse(serder, last=True) - def witnesser(self): """This method name does not match logic??? """ diff --git a/tests/app/test_grouping.py b/tests/app/test_grouping.py index 5df6a805b..2bfcf3e35 100644 --- a/tests/app/test_grouping.py +++ b/tests/app/test_grouping.py @@ -37,7 +37,7 @@ def test_counselor(): parsing.Parser().parse(ims=bytearray(icp3), kvy=kev2) smids = [hab1.pre, hab2.pre, hab3.pre] - rmids = None # need to fixe this + rmids = [hab1.pre, hab2.pre, hab3.pre] inits = dict(isith='["1/2", "1/2", "1/2"]', nsith='["1/2", "1/2", "1/2"]', toad=0, wits=[]) # Create group hab with init params @@ -84,7 +84,7 @@ def test_counselor(): migers = [hab1.kever.ndigers[0], hab2.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab.rotate(isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) + rot = ghab.rotate(smids=smids, rmids=rmids, isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) counselor.start(ghab=ghab, prefixer=prefixer, seqner=seqner, saider=coring.Saider(qb64=rserder.said)) @@ -139,7 +139,7 @@ def test_counselor(): migers = [hab1.kever.ndigers[0], hab2.kever.ndigers[0], hab3.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab.rotate(isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) + rot = ghab.rotate(smids=smids, rmids=rmids, isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) counselor.start(ghab=ghab, prefixer=prefixer, seqner=seqner, saider=coring.Saider(qb64=rserder.said)) @@ -195,7 +195,7 @@ def test_counselor(): migers = [hab1.kever.ndigers[0], hab3.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab.rotate(isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) + rot = ghab.rotate(smids=smids, rmids=rmids, isith="2", nsith="2", toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) counselor.start(ghab=ghab, prefixer=prefixer, seqner=seqner, saider=coring.Saider(qb64=rserder.said)) @@ -274,7 +274,7 @@ def test_the_seven(): parsing.Parser().parse(ims=bytearray(icp), kvy=kev) smids = [hab1.pre, hab2.pre, hab3.pre, hab4.pre, hab5.pre, hab6.pre, hab7.pre] - rmids = None # need to fixe this + rmids = [hab1.pre, hab2.pre, hab3.pre, hab4.pre, hab5.pre, hab6.pre, hab7.pre] inits = dict(isith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', toad=0, wits=[]) @@ -376,7 +376,7 @@ def test_the_seven(): hab5.kever.ndigers[0], hab6.kever.ndigers[0], hab7.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab.rotate(isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', + rot = ghab.rotate(smids=smids, rmids=rmids, isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) @@ -440,7 +440,7 @@ def test_the_seven(): hab5.kever.ndigers[0], hab6.kever.ndigers[0], hab7.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab.rotate(isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', + rot = ghab.rotate(smids=smids, rmids=rmids, isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3", "1/3", "1/3", "1/3", "1/3"]', toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) @@ -519,7 +519,7 @@ def test_the_seven(): migers = [hab4.kever.ndigers[0], hab5.kever.ndigers[0], hab6.kever.ndigers[0]] prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=ghab.kever.sn + 1) - rot = ghab4.rotate(isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3"]', + rot = ghab4.rotate(smids=smids, rmids=rmids, isith='["1/3", "1/3", "1/3"]', nsith='["1/3", "1/3", "1/3"]', toad=0, cuts=list(), adds=list(), verfers=merfers, digers=migers) rserder = serdering.SerderKERI(raw=rot) @@ -673,6 +673,100 @@ def test_multisig_rotate(mockHelpingNowUTC): assert data["gid"] == ghab1.pre assert "rot" in exn.ked["e"] +def test_multisig_rotate_new_group_member_updates_smids(mockHelpingNowUTC): + # Create a multisig with three members, test_1, test_2, and test_3 + with openMultiSig(prefix="test") as ((hby1, ghab1), (hby2, ghab2), (hby3, ghab3)): + # Create a new member, test_4 + with habbing.openHab(name="test_4", salt=b'0123456789abcdef', transferable=True, temp=True) as (hby4, hab4): + icp4 = hab4.makeOwnEvent(sn=0) # Get test_4's inception event to introduce to group members + + hab1 = hby1.habByName("test_1") + hab2 = hby2.habByName("test_2") + hab3 = hby3.habByName("test_3") + # Create member Kevery instances to parse each other's events and update their keystate + kev1 = eventing.Kevery(db=hab1.db, lax=True, local=False) + kev2 = eventing.Kevery(db=hab2.db, lax=True, local=False) + kev3 = eventing.Kevery(db=hab3.db, lax=True, local=False) + kev4 = eventing.Kevery(db=hab4.db, lax=True, local=False) + + # Introduce test_4 member to group by parsing test_4's inception event (latest key state) + parsing.Parser().parse(ims=bytearray(icp4), kvy=kev1) + parsing.Parser().parse(ims=bytearray(icp4), kvy=kev2) + parsing.Parser().parse(ims=bytearray(icp4), kvy=kev3) + # introduce each member to 4 + parsing.Parser().parse(ims=bytearray(hab1.makeOwnEvent(sn=0)), kvy=kev4) + parsing.Parser().parse(ims=bytearray(hab2.makeOwnEvent(sn=0)), kvy=kev4) + parsing.Parser().parse(ims=bytearray(hab3.makeOwnEvent(sn=0)), kvy=kev4) + + # rotate each individual hab to satisfy the rotation threshold with new keys + hab1.rotate() + hab2.rotate() + hab3.rotate() + + # Update keystate in each hab for each other member + rot1 = hab1.makeOwnEvent(sn=1) # get latest event for hab1 and update keystate for other members + parsing.Parser().parse(ims=bytearray(rot1), kvy=kev2) + parsing.Parser().parse(ims=bytearray(rot1), kvy=kev3) + parsing.Parser().parse(ims=bytearray(rot1), kvy=kev4) + + rot2 = hab2.makeOwnEvent(sn=1) # get latest event for hab2 and update keystate for other members + parsing.Parser().parse(ims=bytearray(rot2), kvy=kev1) + parsing.Parser().parse(ims=bytearray(rot2), kvy=kev3) + parsing.Parser().parse(ims=bytearray(rot2), kvy=kev4) + + rot3 = hab3.makeOwnEvent(sn=1) # get latest event for hab3 and update keystate for other members + parsing.Parser().parse(ims=bytearray(rot3), kvy=kev1) + parsing.Parser().parse(ims=bytearray(rot3), kvy=kev2) + parsing.Parser().parse(ims=bytearray(rot3), kvy=kev4) + + # create signing and rotation member AID lists for upcoming rotation + smids = [hab1.pre, hab2.pre, hab3.pre, hab4.pre] + rmids = [hab1.pre, hab2.pre, hab3.pre, hab4.pre] + + # make group hab for test_4 + ghab4 = hby4.joinGroupHab(hab4.pre, group="test_group4", mhab=hab4, smids=smids, rmids=rmids) + + isith = '["1/4", "1/4", "1/4", "1/4"]' + nsith = '["1/4", "1/4", "1/4", "1/4"]' + merfers = [hab1.kever.verfers[0], hab2.kever.verfers[0], hab3.kever.verfers[0], hab4.kever.verfers[0]] + migers = [hab1.kever.ndigers[0], hab2.kever.ndigers[0], hab3.kever.ndigers[0], hab4.kever.ndigers[0]] + rot = ghab1.rotate(smids=smids, rmids=rmids, isith=isith, nsith=nsith, toad=None, cuts=None, adds=None, data=None, + verfers=merfers, digers=migers) + rserder = serdering.SerderKERI(raw=rot) + + # start counselor for group hab 1 + prefixer = coring.Prefixer(qb64=ghab1.pre) + seqner = coring.Seqner(sn=ghab1.kever.sn + 1) + saider = coring.Saider(qb64=rserder.said) + counselor = grouping.Counselor(hby=hby1) + counselor.start(ghab=ghab1, prefixer=prefixer, seqner=seqner, saider=saider) + + # hab2 signs rotation event and parse into hab1 Kevery + sigers2 = hab2.mgr.sign(rserder.raw, verfers=hab2.kever.verfers, indexed=True, indices=[1]) + msg2 = eventing.messagize(serder=rserder, sigers=sigers2) + parsing.Parser().parse(ims=bytearray(msg2), kvy=kev1) + + # hab3 signs rotation event and parse into hab1 Kevery + sigers3 = hab3.mgr.sign(rserder.raw, verfers=hab3.kever.verfers, indexed=True, indices=[2]) + msg3 = eventing.messagize(serder=rserder, sigers=sigers3) + parsing.Parser().parse(ims=bytearray(msg3), kvy=kev1) + + # hab4 signs rotation event and parse into hab1 Kevery. This should commit the event + sigers4 = hab4.mgr.sign(rserder.raw, verfers=hab4.kever.verfers, indexed=True, indices=[3]) + msg4 = eventing.messagize(serder=rserder, sigers=sigers4) + parsing.Parser().parse(ims=bytearray(msg4), kvy=kev1) + + kev1.processEscrows() # Runs escrows for Kevery1 so he processes all sigs together + + counselor.processEscrows() # Get the rest of the way through counselor. + assert counselor.complete(prefixer=prefixer, seqner=seqner, saider=saider) + assert ghab4.smids == smids + assert ghab4.rmids == rmids + hby1.loadHabs() + ghab1 = hby1.habByName("test_group1") # reload hab to get updated smids and rmids values + assert ghab1.smids == smids + assert ghab1.rmids == rmids + def test_multisig_interact(mockHelpingNowUTC): with openMultiSig(prefix="test") as ((hby1, ghab1), (_, _), (_, _)): From 41ce1adaa4c67275b9f1bf67103f1a7c3762d491 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Fri, 4 Oct 2024 12:16:56 -0700 Subject: [PATCH 29/61] Version Bump --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f22f2a226..1efbe334b 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.18 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.18-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.19 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.19-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.18 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.18-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.19 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.19-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index 8936cf55c..e4491599d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.18` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.19` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index e29a9fd29..8dbbf6624 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.18', # also change in src/keri/__init__.py + version='1.1.19', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index b33bc909f..4fbdf1e23 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.18' # also change in setup.py +__version__ = '1.1.19' # also change in setup.py From 214a89d67baf7f063bf1051954ee281c07189964 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Mon, 14 Oct 2024 07:09:50 -0700 Subject: [PATCH 30/61] Version Bump Signed-off-by: pfeairheller --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1efbe334b..7954bd398 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.19 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.19-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.20 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.20-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.19 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.19-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.20 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.20-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index e4491599d..b44250174 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.19` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.20` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 8dbbf6624..5b644d607 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.19', # also change in src/keri/__init__.py + version='1.1.20', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 4fbdf1e23..b833381ab 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.19' # also change in setup.py +__version__ = '1.1.20' # also change in setup.py From 1d1d76dea0011faf6c68037f9af5054226d75163 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Thu, 24 Oct 2024 11:08:16 -0600 Subject: [PATCH 31/61] cherry pick migration commit and add name fix (#879) * feat: add database migrations up to 1.2.0 (#874) including database migrations for 0.6.7 (None) -> 0.6.8, 0.6.8 -> 1.0.0, 1.0.0 -> 1.2.0 * fix: preserve name from 0.6.7 -> 0.6.8 * chore: remove unused db in 1.1.x releases --- setup.py | 3 +- src/keri/app/cli/commands/migrate.py | 163 ------------------ src/keri/app/cli/commands/migrate/__init__.py | 0 src/keri/app/cli/commands/migrate/list.py | 64 +++++++ src/keri/app/cli/commands/migrate/run.py | 67 +++++++ src/keri/app/cli/commands/migrate/show.py | 59 +++++++ src/keri/app/cli/commands/version.py | 23 ++- src/keri/app/cli/common/existing.py | 4 +- src/keri/app/habbing.py | 2 +- src/keri/db/basing.py | 113 +++++++++++- src/keri/db/dbing.py | 66 ++++++- src/keri/db/migrations/__init__.py | 0 .../add_key_and_reg_state_schemas.py | 150 ++++++++++++++++ src/keri/db/migrations/hab_data_rename.py | 88 ++++++++++ 14 files changed, 630 insertions(+), 172 deletions(-) delete mode 100644 src/keri/app/cli/commands/migrate.py create mode 100644 src/keri/app/cli/commands/migrate/__init__.py create mode 100644 src/keri/app/cli/commands/migrate/list.py create mode 100644 src/keri/app/cli/commands/migrate/run.py create mode 100644 src/keri/app/cli/commands/migrate/show.py create mode 100644 src/keri/db/migrations/__init__.py create mode 100644 src/keri/db/migrations/add_key_and_reg_state_schemas.py create mode 100644 src/keri/db/migrations/hab_data_rename.py diff --git a/setup.py b/setup.py index 5b644d607..e59ff0270 100644 --- a/setup.py +++ b/setup.py @@ -87,7 +87,8 @@ 'mnemonic>=0.21', 'PrettyTable>=3.10.0', 'http_sfv>=0.9.9', - 'cryptography>=42.0.5' + 'cryptography>=42.0.5', + 'semver>=3.0.2' ], extras_require={ }, diff --git a/src/keri/app/cli/commands/migrate.py b/src/keri/app/cli/commands/migrate.py deleted file mode 100644 index 775f957b9..000000000 --- a/src/keri/app/cli/commands/migrate.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- encoding: utf-8 -*- -""" -KERI -keri.kli.commands module - -""" -import argparse - -from hio import help -from hio.base import doing - -from keri import kering -from keri.app.cli.common import existing -from keri.core import coring, serdering -from keri.db import koming, subing, dbing -from keri.db.basing import KeyStateRecord, StateEERecord -from keri.kering import ConfigurationError, Version -from keri.vdr import viring - -logger = help.ogler.getLogger() - -parser = argparse.ArgumentParser(description='View status of a local AID') -parser.set_defaults(handler=lambda args: handler(args), - transferable=True) -parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) -parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', - required=False, default="") -parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', - dest="bran", default=None) # passcode => bran -parser.add_argument('--force', action="store_true", required=False, - help='True means perform migration without prompting the user') - - -def handler(args): - if not args.force: - print() - print("This command will migrate your datastore to the next version of KERIpy and is not reversible.") - print("After this command, you will not be able to access your data store with this version.") - print() - yn = input("Are you sure you want to continue? [y|N]: ") - - if yn not in ("y", "Y"): - print("...exiting") - return [] - - kwa = dict(args=args) - return [doing.doify(migrate, **kwa)] - - -def migrate(tymth, tock=0.0, **opts): - """ Command line status handler - - """ - _ = (yield tock) - args = opts["args"] - name = args.name - base = args.base - bran = args.bran - - try: - with dbing.openLMDB(name=name, base=base, bran=bran, temp=False) as db: - print(db.path) - states = koming.Komer(db=db, - schema=dict, - subkey='stts.') - nstates = koming.Komer(db=db, - schema=KeyStateRecord, - subkey='stts.') - - for keys, sad in states.getItemIter(): - ksr = KeyStateRecord( - vn=Version, # version number as list [major, minor] - i=sad['i'], # qb64 prefix - s=sad['s'], # lowercase hex string no leading zeros - p=sad['p'], - d=sad['d'], - f=sad['f'], # lowercase hex string no leading zeros - dt=sad['dt'], - et=sad['et'], - kt=sad['kt'], - k=sad['k'], - nt=sad['nt'], - n=sad['n'], - bt=sad['bt'], - b=sad['b'], - c=sad['c'], - ee=StateEERecord._fromdict(sad['ee']), # latest est event dict - di=sad['di'] if sad['di'] else None - ) - - nstates.pin(keys=keys, val=ksr) - - with existing.existingHby(name=name, base=base, bran=bran) as hby: - rgy = viring.Reger(name=name, base=base, db=hby.db, temp=False, - reopen=True) - - rstates = koming.Komer(db=rgy, - schema=dict, - subkey='stts.') - - for _, sad in rstates.getItemIter(): - rsr = viring.RegStateRecord( - vn=list(Version), # version number as list [major, minor] - i=sad['i'], # qb64 registry SAID - s=sad['s'], # lowercase hex string no leading zeros - d=sad['d'], - ii=sad['ii'], - dt=sad['dt'], - et=sad['et'], - bt=sad['bt'], # hex string no leading zeros lowercase - b=sad['b'], # list of qb64 may be empty - c=sad['c'], - ) - # ksr = stateFromKever(kever) - rgy.states.pin(sad['i'], val=rsr) - - for (said,), _ in rgy.saved.getItemIter(): - snkey = dbing.snKey(said, 0) - dig = rgy.getTel(key=snkey) - - prefixer = coring.Prefixer(qb64=said) - seqner = coring.Seqner(sn=0) - saider = coring.Saider(qb64b=bytes(dig)) - rgy.cancs.pin(keys=said, val=[prefixer, seqner, saider]) - - migrateKeys(hby.db) - - # clear escrows - print("clearing escrows") - hby.db.gpwe.trim() - hby.db.gdee.trim() - hby.db.dpwe.trim() - hby.db.gpse.trim() - hby.db.epse.trim() - hby.db.dune.trim() - - except ConfigurationError: - print(f"identifier prefix for {name} does not exist, incept must be run first", ) - return -1 - - -def migrateKeys(db): - # public keys mapped to the AID and event seq no they appeared in - pubs = subing.CatCesrIoSetSuber(db=db, subkey="pubs.", - klas=(coring.Prefixer, coring.Seqner)) - - # next key digests mapped to the AID and event seq no they appeared in - digs = subing.CatCesrIoSetSuber(db=db, subkey="digs.", - klas=(coring.Prefixer, coring.Seqner)) - - for pre, fn, dig in db.getFelItemAllPreIter(key=b''): - dgkey = dbing.dgKey(pre, dig) # get message - if not (raw := db.getEvt(key=dgkey)): - print(f"Migrate keys: missing event for dig={dig}, skipped.") - continue - serder = serdering.SerderKERI(raw=bytes(raw)) - val = (coring.Prefixer(qb64b=serder.preb), coring.Seqner(sn=serder.sn)) - verfers = serder.verfers or [] - for verfer in verfers: - pubs.add(keys=(verfer.qb64,), val=val) - ndigers = serder.ndigers or [] - for diger in ndigers: - digs.add(keys=(diger.qb64,), val=val) diff --git a/src/keri/app/cli/commands/migrate/__init__.py b/src/keri/app/cli/commands/migrate/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/keri/app/cli/commands/migrate/list.py b/src/keri/app/cli/commands/migrate/list.py new file mode 100644 index 000000000..a88360e42 --- /dev/null +++ b/src/keri/app/cli/commands/migrate/list.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- +""" +keri.kli.commands.migrate.list module + +""" +import argparse +import logging + +from keri import help +from hio.base import doing +from prettytable import PrettyTable + +from keri.app.cli.common import existing + +logger = help.ogler.getLogger() + +def handler(args): + """ + List local LMDB database migrations and their completion status + + Args: + args(Namespace): arguments object from command line + """ + lister = ListDoer(args) + return [lister] + + +parser = argparse.ArgumentParser(description='Lists the local LMDB migrations and their completion status') +parser.set_defaults(handler=handler, + transferable=True) + +# Parameters for basic structure of database +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--temp', '-t', help='create a temporary keystore, used for testing', default=False) + +# Parameters for Manager creation +# passcode => bran +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) + + +class ListDoer(doing.Doer): + + def __init__(self, args): + self.args = args + super(ListDoer, self).__init__() + + def recur(self, tyme): + tab = PrettyTable() + tab.field_names = ["Num", "Name", "Date Completed"] + tab.align["Name"] = "l" + + hby = existing.setupHby(name=self.args.name, base=self.args.base, + bran=self.args.bran if self.args.bran else None, temp=self.args.temp) + + for idx, (name, dater) in enumerate(hby.db.complete()): + print(name, dater) + date = dater.datetime.strftime("%Y-%m-%d %H:%M") if dater is not None else "Not Run" + tab.add_row((f"{idx + 1}", f"{name}", date)) + + print(tab) + return True diff --git a/src/keri/app/cli/commands/migrate/run.py b/src/keri/app/cli/commands/migrate/run.py new file mode 100644 index 000000000..499ed3ebb --- /dev/null +++ b/src/keri/app/cli/commands/migrate/run.py @@ -0,0 +1,67 @@ +# -*- encoding: utf-8 -*- +""" +keri.kli.commands.migrate.run module + +""" +import argparse + +from hio.base import doing + +from keri import help +from keri import kering +from keri.db import basing + +logger = help.ogler.getLogger("keri") + +def handler(args): + """ + Launch KERI database migrator + + Args: + args(Namespace): arguments object from command line + """ + migrator = MigrateDoer(args) + return [migrator] + + +parser = argparse.ArgumentParser(description='Migrates a database and keystore') +parser.set_defaults(handler=handler, + transferable=True) + +# Parameters for basic structure of database +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--temp', '-t', help='create a temporary keystore, used for testing', default=False) + +# Parameters for Manager creation +# passcode => bran +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) + + +class MigrateDoer(doing.Doer): + + def __init__(self, args): + self.args = args + super(MigrateDoer, self).__init__() + + def recur(self, tyme): + name=self.args.name + base=self.args.base + temp=self.args.temp + hab_db = basing.Baser(name=name, + base=base, + temp=temp, + reopen=False) + + try: + hab_db.reopen() + except kering.DatabaseError as ex: + pass + + print(f"Migrating {name}...") + hab_db.migrate() + print(f"Finished migrating {name}") + + return True diff --git a/src/keri/app/cli/commands/migrate/show.py b/src/keri/app/cli/commands/migrate/show.py new file mode 100644 index 000000000..1ff745815 --- /dev/null +++ b/src/keri/app/cli/commands/migrate/show.py @@ -0,0 +1,59 @@ +# -*- encoding: utf-8 -*- +""" +keri.kli.commands module + +""" +import argparse + +from hio import help +from hio.base import doing + +from keri.app.cli.common import existing + +logger = help.ogler.getLogger() + +def handler(args): + """ + Launch KERI database initialization + + Args: + args(Namespace): arguments object from command line + """ + clean = CleanDoer(args) + return [clean] + + +parser = argparse.ArgumentParser(description='Cleans and migrates a database and keystore') +parser.set_defaults(handler=handler, + transferable=True) + +# Parameters for basic structure of database +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--temp', '-t', help='create a temporary keystore, used for testing', default=False) +parser.add_argument('--migration', '-m', help='migration name', required=True) + + +# Parameters for Manager creation +# passcode => bran +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) + + +class CleanDoer(doing.Doer): + + def __init__(self, args): + self.args = args + super(CleanDoer, self).__init__() + + def recur(self, tyme): + hby = existing.setupHby(name=self.args.name, base=self.args.base, + bran=self.args.bran, temp=self.args.temp) + + [(name, dater)] = hby.db.complete(name=self.args.migration) + date = dater.datetime.strftime("%Y-%m-%d %H:%M") if dater is not None else "Not Run" + + print(f"{self.args.migration} -> {date}") + + return True diff --git a/src/keri/app/cli/commands/version.py b/src/keri/app/cli/commands/version.py index 5ea6b775a..98cc81c5a 100644 --- a/src/keri/app/cli/commands/version.py +++ b/src/keri/app/cli/commands/version.py @@ -8,18 +8,35 @@ from hio.base import doing import keri +from keri.app.cli.common import existing parser = argparse.ArgumentParser(description='Print version of KLI') parser.set_defaults(handler=lambda args: handler(args)) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=False, + default=None) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran def handler(args): - return [doing.doify(version)] + kwa = dict(args=args) + return [doing.doify(version, **kwa)] -def version(tymth, tock=0.0): +def version(tymth, tock=0.0, **opts): """ Command line version handler """ _ = (yield tock) - print(keri.__version__) + args = opts["args"] + name = args.name + base = args.base + bran = args.bran + + print(f"Library version: {keri.__version__}") + + if name is not None: + with existing.existingHby(name=name, base=base, bran=bran) as hby: + print(f"Database version: {hby.db.version}") diff --git a/src/keri/app/cli/common/existing.py b/src/keri/app/cli/common/existing.py index 287d4e033..b2feba5e3 100644 --- a/src/keri/app/cli/common/existing.py +++ b/src/keri/app/cli/common/existing.py @@ -12,7 +12,7 @@ from keri.app import habbing, keeping -def setupHby(name, base="", bran=None, cf=None): +def setupHby(name, base="", bran=None, cf=None, temp=False): """ Create Habery off of existing directory Parameters: @@ -27,7 +27,7 @@ def setupHby(name, base="", bran=None, cf=None): """ ks = keeping.Keeper(name=name, base=base, - temp=False, + temp=temp, cf=cf, reopen=True) aeid = ks.gbls.get('aeid') diff --git a/src/keri/app/habbing.py b/src/keri/app/habbing.py index 2eed0d94f..d30f143e3 100644 --- a/src/keri/app/habbing.py +++ b/src/keri/app/habbing.py @@ -2763,7 +2763,7 @@ def rotate(self, serder=None, smids=None, rmids=None, **kwargs): self.rmids = rmids habord.smids = smids habord.rmids = rmids - self.db.habs.pin(keys=(self.name,), val=habord) + self.db.habs.pin(keys=self.name, val=habord) return msg diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index 0f808a8d4..de29cefa1 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -18,7 +18,7 @@ So only need to set dupsort first time opened each other opening does not need to call it """ - +import importlib import os import shutil from collections import namedtuple @@ -30,10 +30,12 @@ import cbor2 as cbor import msgpack import lmdb +import semver from ordered_set import OrderedSet as oset from hio.base import doing +import keri from . import dbing, koming, subing from .. import kering @@ -45,6 +47,11 @@ logger = help.ogler.getLogger() +MIGRATIONS = [ + ("0.6.8", ["hab_data_rename"]), + ("1.0.0", ["add_key_and_reg_state_schemas"]) +] + class dbdict(dict): """ @@ -826,6 +833,10 @@ def reopen(self, **kwa): # events as ordered by first seen ordinals self.fons = subing.CesrSuber(db=self, subkey='fons.', klas=coring.Seqner) + + self.migs = subing.CesrSuber(db=self, subkey="migs.", klas=coring.Dater) + self.vers = subing.Suber(db=self, subkey="vers.") + # Kever state made of KeyStateRecord key states self.states = koming.Komer(db=self, schema=KeyStateRecord, @@ -1060,6 +1071,10 @@ def reload(self): Reload stored prefixes and Kevers from .habs """ + # Check migrations to see if this database is up to date. Error otherwise + if not self.current: + raise kering.DatabaseError(f"Database migrations must be run. DB version {self.version}; current {keri.__version__}") + removes = [] for keys, data in self.habs.getItemIter(): if (ksr := self.states.get(keys=data.hid)) is not None: @@ -1099,6 +1114,102 @@ def reload(self): for keys in removes: # remove bare .habs records self.nmsp.rem(keys=keys) + def migrate(self): + """ Run all migrations required + + Run all migrations that are required from the current version of database up to the current version + of the software that have not already been run. + + Sets the version of the database to the current version of the software after successful completion + of required migrations + + """ + for (version, migrations) in MIGRATIONS: + # Only run migration if current source code version is at or below the migration version + ver = semver.VersionInfo.parse(keri.__version__) + ver_no_prerelease = semver.Version(ver.major, ver.minor, ver.patch) + if self.version is not None and semver.compare(version, str(ver_no_prerelease)) > 0: + print(f"Skipping migration {version} as higher than the current KERI version {keri.__version__}") + continue + # Check to see if migration version is for an older database version + if self.version is not None and semver.compare(version, self.version) != 1: + continue + print(f"Migrating database v{self.version} --> v{version} ...") + + for migration in migrations: + modName = f"keri.db.migrations.{migration}" + if self.migs.get(keys=(migration,)) is not None: + continue + + mod = importlib.import_module(modName) + try: + mod.migrate(self) + except Exception as e: + print(f"\nAbandoning migration {migration} at version {version} with error: {e}") + return + + self.migs.pin(keys=(migration,), val=coring.Dater()) + + # update database version after successful migration + self.version = version + + self.version = keri.__version__ + + @property + def current(self): + """ Current property determines if we are at the current database migration state. + + If the database version matches the library version return True + If the current database version is behind the current library version, check for migrations + - If there are migrations to run, return False + - If there are no migrations to run, reset database version to library version and return True + If the current database version is ahead of the current library version, raise exception + + """ + if self.version == keri.__version__: + return True + + # If database version is ahead of library version, throw exception + ver = semver.VersionInfo.parse(keri.__version__) + ver_no_prerelease = semver.Version(ver.major, ver.minor, ver.patch) + if self.version is not None and semver.compare(self.version, str(ver_no_prerelease)) == 1: + raise kering.ConfigurationError( + f"Database version={self.version} is ahead of library version={keri.__version__}") + + last = MIGRATIONS[-1] + # If we aren't at latest version, but there are no outstanding migrations, + # reset version to latest (rightmost (-1) migration is latest) + if self.migs.get(keys=(last[1][-1],)) is not None: + return True + + # We have migrations to run + return False + + def complete(self, name=None): + """ Returns list of tuples of migrations completed with date of completion + + Parameters: + name(str): optional name of migration to check completeness + + Returns: + list: tuples of migration,date of completed migration names and the date of completion + + """ + migrations = [] + if not name: + for version, migs in MIGRATIONS: + # Only get migration completion dates for migrations that have been run + if self.version is not None and semver.compare(version, self.version) <= 0: + for mig in migs: + dater = self.migs.get(keys=(mig,)) + migrations.append((mig, dater)) + else: + for version, migs in MIGRATIONS: # check all migrations for each version + if name not in migs or not self.migs.get(keys=(name,)): + raise ValueError(f"No migration named {name}") + migrations.append((name, self.migs.get(keys=(name,)))) + + return migrations def clean(self): """ diff --git a/src/keri/db/dbing.py b/src/keri/db/dbing.py index d3831e214..bc8a9ac67 100644 --- a/src/keri/db/dbing.py +++ b/src/keri/db/dbing.py @@ -59,6 +59,7 @@ from hio.base import filing +import keri from ..help import helping ProemSize = 32 # does not include trailing separator @@ -345,6 +346,7 @@ def __init__(self, readonly=False, **kwa): """ self.env = None + self._version = None self.readonly = True if readonly else False super(LMDBer, self).__init__(**kwa) @@ -374,6 +376,7 @@ def reopen(self, readonly=False, **kwa): readonly (bool): True means open database in readonly mode False means open database in read/write mode """ + exists = self.exists(name=self.name, base=self.base) opened = super(LMDBer, self).reopen(**kwa) if readonly is not None: self.readonly = readonly @@ -382,10 +385,45 @@ def reopen(self, readonly=False, **kwa): # creates files data.mdb and lock.mdb in .dbDirPath self.env = lmdb.open(self.path, max_dbs=self.MaxNamedDBs, map_size=104857600, mode=self.perm, readonly=self.readonly) + self.opened = True if opened and self.env else False + + if self.opened and not self.readonly and (not exists or self.temp): + self.version = keri.__version__ + return self.opened + + @property + def version(self): + """ Return the version of database stored in __version__ key. + + This value is read through cached in memory + + Returns: + str: the version of the database or None if not set in the database + + """ + if self._version is None: + self._version = self.getVer() + + return self._version + + @version.setter + def version(self, val): + """ Set the version of the database in memory and in the __version__ key + + Parameters: + val (str): The new semver formatted version of the database + + """ + if hasattr(val, "decode"): + val = val.decode("utf-8") # convert bytes to str + + self._version = val + self.setVer(self._version) + def close(self, clear=False): """ Close lmdb at .env and if clear or .temp then remove lmdb directory at .path @@ -400,7 +438,33 @@ def close(self, clear=False): self.env = None - return(super(LMDBer, self).close(clear=clear)) + return (super(LMDBer, self).close(clear=clear)) + + def getVer(self): + """ Returns the value of the the semver formatted version in the __version__ key in this database + + Returns: + str: semver formatted version of the database + + """ + with self.env.begin() as txn: + cursor = txn.cursor() + version = cursor.get(b'__version__') + return version.decode("utf-8") if version is not None else None + + def setVer(self, val): + """ Set the version of the database in the __version__ key + + Parameters: + val (str): The new semver formatted version of the database + + """ + if hasattr(val, "encode"): + val = val.encode("utf-8") # convert str to bytes + + with self.env.begin(write=True) as txn: + cursor = txn.cursor() + cursor.replace(b'__version__', val) # For subdbs with no duplicate values allowed at each key. (dupsort==False) diff --git a/src/keri/db/migrations/__init__.py b/src/keri/db/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/keri/db/migrations/add_key_and_reg_state_schemas.py b/src/keri/db/migrations/add_key_and_reg_state_schemas.py new file mode 100644 index 000000000..c626bd2fb --- /dev/null +++ b/src/keri/db/migrations/add_key_and_reg_state_schemas.py @@ -0,0 +1,150 @@ +from keri import help +from keri.core import coring, serdering +from keri.db import koming, subing, dbing +from keri.db.basing import StateEERecord, KeyStateRecord +from keri.db.dbing import dgKey, splitKey +from keri.kering import ConfigurationError, Version +from keri.vdr import viring + +logger = help.ogler.getLogger() + +def _check_if_needed(db): + states = koming.Komer(db=db, + schema=dict, + subkey='stts.') + first = next(states.getItemIter(), None) + if first is None: + return False + keys, sad = first + if 'vn' in sad: + return False + return True + +def migrate(db): + """Adds schema for KeyStateRecord , RegStateRecord, and migrates the rgy.cancs., hby.db.pubs., + and hby.db.digs. to be up to date as of 2022-??-?? + + This migration performs the following: + - hby.db -> "stts." schema from dict -> KeyStateRecord + - rgy -> "stts." schema from dict -> RegStateRecord + - rgy -> "cancs." reset to (ACDC SAID, SN 0, TEL evt 0 digest) + - hby.db -> "pubs." and + hby.db -> "digs." + that don't exist are populated with verification keys and event digests for the first seen events and + Keys: + "pubs." Verfer of each Verfer for each FEL event + "digs." Diger of next Diger (ndiger) of each FEL event + Value: (prefix, sn) of each event + + Parameters: + db(Baser): Baser database object on which to run the migration + """ + # May be running on a database that is already in the right state yet has no migrations run + # so we need to check if the migration is needed + if not _check_if_needed(db): + print(f"{__name__} migration not needed, already ran") + return + + try: + logger.debug(f"Migrating keystate and regstate dict to schema for {db.path}") + states = koming.Komer(db=db, + schema=dict, + subkey='stts.') + nstates = koming.Komer(db=db, + schema=KeyStateRecord, + subkey='stts.') + + for keys, sad in states.getItemIter(): + ksr = KeyStateRecord( + vn=Version, # version number as list [major, minor] + i=sad['i'], # qb64 prefix + s=sad['s'], # lowercase hex string no leading zeros + p=sad['p'], + d=sad['d'], + f=sad['f'], # lowercase hex string no leading zeros + dt=sad['dt'], + et=sad['et'], + kt=sad['kt'], + k=sad['k'], + nt=sad['nt'], + n=sad['n'], + bt=sad['bt'], + b=sad['b'], + c=sad['c'], + ee=StateEERecord._fromdict(sad['ee']), # latest est event dict + di=sad['di'] if sad['di'] else None + ) + + nstates.pin(keys=keys, val=ksr) + + rgy = viring.Reger(name=db.name, base=db.base, db=db, temp=db.temp, reopen=True) + + rstates = koming.Komer(db=rgy, + schema=dict, + subkey='stts.') + + for _, sad in rstates.getItemIter(): + rsr = viring.RegStateRecord( + vn=list(Version), # version number as list [major, minor] + i=sad['i'], # qb64 registry SAID + s=sad['s'], # lowercase hex string no leading zeros + d=sad['d'], + ii=sad['ii'], + dt=sad['dt'], + et=sad['et'], + bt=sad['bt'], # hex string no leading zeros lowercase + b=sad['b'], # list of qb64 may be empty + c=sad['c'], + ) + rgy.states.pin(sad['i'], val=rsr) + + for (said,), _ in rgy.saved.getItemIter(): + snkey = dbing.snKey(said, 0) + dig = rgy.getTel(key=snkey) + + prefixer = coring.Prefixer(qb64=said) + seqner = coring.Seqner(sn=0) + saider = coring.Saider(qb64b=bytes(dig)) + rgy.cancs.pin(keys=said, val=[prefixer, seqner, saider]) + + migrateKeys(db) + + # clear escrows + logger.info("clearing escrows") + db.gpwe.trim() + db.gdee.trim() + db.dpwe.trim() + db.gpse.trim() + db.epse.trim() + db.dune.trim() + for ekey, edig in db.getQnfItemsNextIter(): + pre, _ = splitKey(ekey) + db.delQnf(dgKey(pre, edig), edig) + + except ConfigurationError: + logger.error(f"identifier prefix for {db.name} does not exist, incept must be run first", ) + return -1 + + +def migrateKeys(db): + # public keys mapped to the AID and event seq no they appeared in + pubs = subing.CatCesrIoSetSuber(db=db, subkey="pubs.", + klas=(coring.Prefixer, coring.Seqner)) + + # next key digests mapped to the AID and event seq no they appeared in + digs = subing.CatCesrIoSetSuber(db=db, subkey="digs.", + klas=(coring.Prefixer, coring.Seqner)) + + for pre, fn, dig in db.getFelItemAllPreIter(key=b''): + dgkey = dbing.dgKey(pre, dig) # get message + if not (raw := db.getEvt(key=dgkey)): + logger.info(f"Migrate keys: missing event for dig={dig}, skipped.") + continue + serder = serdering.SerderKERI(raw=bytes(raw)) + val = (coring.Prefixer(qb64b=serder.preb), coring.Seqner(sn=serder.sn)) + verfers = serder.verfers or [] + for verfer in verfers: + pubs.add(keys=(verfer.qb64,), val=val) + ndigers = serder.ndigers or [] + for diger in ndigers: + digs.add(keys=(diger.qb64,), val=val) diff --git a/src/keri/db/migrations/hab_data_rename.py b/src/keri/db/migrations/hab_data_rename.py new file mode 100644 index 000000000..7ac814514 --- /dev/null +++ b/src/keri/db/migrations/hab_data_rename.py @@ -0,0 +1,88 @@ +from dataclasses import dataclass, field, asdict +from typing import Optional + +from keri.db import koming, basing +from keri.db.basing import HabitatRecord, Baser +from keri.vdr.viring import Reger + + +@dataclass +class HabitatRecordV0_6_7: # baser.habs + """ + Habitat application state information keyed by habitat name (baser.habs) + + Attributes: + prefix (str): identifier prefix of hab qb64 + pid (str | None): group member identifier qb64 when hid is group + aids (list | None): group signing member identifiers qb64 when hid is group + watchers: (list[str]) = list of id prefixes qb64 of watchers + """ + prefix: str # aid qb64 + pid: Optional[str] # participant aid of group aid + aids: Optional[list] # all identifiers participating in the group identity + + watchers: list[str] = field(default_factory=list) # aids qb64 of watchers + +def _check_if_needed(db): + """ + Check if the migration is needed + + Parameters: + db(Baser): Baser database object on which to run the migration + + Returns: + bool: True if the migration is needed, False otherwise + """ + habs = koming.Komer(db=db, subkey='habs.', schema=dict, ) + first = next(habs.getItemIter(), None) + if first is None: + return False + name, habord = first + if 'prefix' in habord: + return True + return False + +def migrate(db): + """Rename data in HabitatRecord from the old labels to the new labels as of 2022-10-17 + + This migration performs the following: + 1. rename prefix -> hid + 2. rename pid -> mid + 3. rename aids -> smids, rmids + + Parameters: + db(Baser): Baser database object on which to run the migration + """ + # May be running on a database that is already in the right state yet has no migrations run + # so we need to check if the migration is needed + if not _check_if_needed(db): + print(f"{__name__} migration not needed, already ran") + return + + habs = koming.Komer(db=db, + subkey='habs.', + schema=HabitatRecordV0_6_7, ) + + habords = dict() + # Update Hab records from .habs with name + for name, habord in habs.getItemIter(): + existing = asdict(habord) + habord_0_6_7 = HabitatRecordV0_6_7(**existing) + habord_0_6_8 = HabitatRecord( + hid=habord_0_6_7.prefix, + mid=habord_0_6_7.pid, + smids=habord_0_6_7.aids, + rmids=habord_0_6_7.aids, + sid=None, + watchers=habord_0_6_7.watchers + ) + habords[name] = habord_0_6_8 + + habs.trim() # remove existing records + + # Add in the renamed records + for name, habord in habords.items(): + (name,) = name + db.habs.pin(keys=(name,), val=habord) + + From f96d746dce8d9ea9458c0506c72ad0c4c4563a51 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 24 Oct 2024 14:13:15 -0400 Subject: [PATCH 32/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 7954bd398..48a50ab90 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.20 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.20-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.21 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.21-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.20 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.20-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.21 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.21-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index b44250174..f60cd7146 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.20` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.21` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index e59ff0270..da42d968c 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.20', # also change in src/keri/__init__.py + version='1.1.21', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index b833381ab..1ab2acb39 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.20' # also change in setup.py +__version__ = '1.1.21' # also change in setup.py From 329998788b62d86dfffe3d721018cde52ee9068e Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Thu, 14 Nov 2024 22:55:47 +0700 Subject: [PATCH 33/61] feat: KERI_LMDB_MAP_SIZE for setting LMDB file size (#889) --- docs/keri_db.rst | 2 ++ src/keri/db/dbing.py | 7 ++++++- tests/db/test_dbing.py | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/keri_db.rst b/docs/keri_db.rst index e2354b170..14327b0fc 100644 --- a/docs/keri_db.rst +++ b/docs/keri_db.rst @@ -13,6 +13,8 @@ keri.db.dbing .. automodule:: keri.db.dbing :members: +The `KERI_LMDB_MAP_SIZE` environment variable can be used to set the size of the LMDB map. The default size is 4GB. + keri.db.escrowing ----------------- diff --git a/src/keri/db/dbing.py b/src/keri/db/dbing.py index bc8a9ac67..532fe8a7c 100644 --- a/src/keri/db/dbing.py +++ b/src/keri/db/dbing.py @@ -383,7 +383,12 @@ def reopen(self, readonly=False, **kwa): # open lmdb major database instance # creates files data.mdb and lock.mdb in .dbDirPath - self.env = lmdb.open(self.path, max_dbs=self.MaxNamedDBs, map_size=104857600, + map_size = os.getenv("KERI_LMDB_MAP_SIZE", '4294967296') # 4GB + try: + map_size = int(map_size) + except ValueError: + map_size = 4 * 1024**3 # 4GB + self.env = lmdb.open(self.path, max_dbs=self.MaxNamedDBs, map_size=map_size, mode=self.perm, readonly=self.readonly) self.opened = True if opened and self.env else False diff --git a/tests/db/test_dbing.py b/tests/db/test_dbing.py index c88cca4f8..56c1fa40a 100644 --- a/tests/db/test_dbing.py +++ b/tests/db/test_dbing.py @@ -227,8 +227,15 @@ def test_lmdber(): assert databaser.path == None assert databaser.env == None + os.environ['KERI_LMDB_MAP_SIZE'] = f'{2 * 1024**3}' # 2GB databaser.reopen() assert databaser.opened + assert databaser.env.info()['map_size'] == 2 * 1024**3 # 2GB + + os.environ['KERI_LMDB_MAP_SIZE'] = f'invalid-size' # will trigger default + databaser.reopen() + assert databaser.opened + assert databaser.env.info()['map_size'] == 4 * 1024 ** 3 # 4GB default value assert isinstance(databaser.env, lmdb.Environment) assert databaser.path.endswith("keri/db/main") assert databaser.env.path() == databaser.path From d16b2aeb1eab81a4c5426884df73829a1426c758 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 14 Nov 2024 11:08:12 -0500 Subject: [PATCH 34/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 8 ++++---- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 48a50ab90..042b1374f 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: build-keri build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.21 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.21-arm64 . + @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.22 . + @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.22-arm64 . .PHONY: build-witness-demo build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.21 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.21-arm64 . + @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.22 . + @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.22-arm64 . .PHONY: publish-keri publish-keri: diff --git a/README.md b/README.md index f60cd7146..8c9bd01ed 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.21` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.22` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index da42d968c..72408885d 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.21', # also change in src/keri/__init__.py + version='1.1.22', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 1ab2acb39..e63adf6cb 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.21' # also change in setup.py +__version__ = '1.1.22' # also change in setup.py From 4fb13eff5f1eb10d62974eabb7c2ca66d016658f Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Wed, 20 Nov 2024 09:42:38 -0500 Subject: [PATCH 35/61] adds multi architecture build (#891) Signed-off-by: Kevin Griffin --- Makefile | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 042b1374f..af46a7fff 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,34 @@ .PHONY: build-keri -build-keri: - @docker buildx build --platform=linux/amd64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.22 . - @docker buildx build --platform=linux/arm64 -f images/keripy.dockerfile --tag weboftrust/keri:1.1.22-arm64 . -.PHONY: build-witness-demo -build-witness-demo: - @@docker buildx build --platform=linux/amd64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.22 . - @@docker buildx build --platform=linux/arm64 -f images/witness.demo.dockerfile --tag weboftrust/keri-witness-demo:1.1.22-arm64 . +VERSION=1.1.22 -.PHONY: publish-keri -publish-keri: - @docker push weboftrust/keri --all-tags +define DOCKER_WARNING +In order to use the multi-platform build enable the containerd image store +The containerd image store is not enabled by default. +To enable the feature for Docker Desktop: + Navigate to Settings in Docker Desktop. + In the General tab, check Use containerd for pulling and storing images. + Select Apply and Restart." +endef + +build-keri: .warn + @docker build --platform=linux/amd64,linux/arm64 -f images/keripy.dockerfile -t weboftrust/keri:$(VERSION) . + +.PHONY: build-witness-demo +build-witness-demo: .warn + @docker build --platform=linux/amd64,linux/arm64 -f images/witness.demo.dockerfile -t weboftrust/keri-witness-demo:1.1.10 . .PHONY: publish-keri-witness-demo publish-keri-witness-demo: - @docker push weboftrust/keri-witness-demo --all-tags \ No newline at end of file + @docker push weboftrust/keri-witness-demo --all-tags + +publish-keri: + @docker push weboftrust/keri:$(VERSION) + +.warn: + @echo -e ${RED}"$$DOCKER_WARNING"${NO_COLOUR} + +RED="\033[0;31m" +NO_COLOUR="\033[0m" +export DOCKER_WARNING From 5cc5e2a6d35eb3fe1cbb861ed7f2dba753097ac4 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Mon, 25 Nov 2024 05:11:22 -0700 Subject: [PATCH 36/61] Clear both KEL and TEL escrows; list all events in escrow, or their counts (#894) * feat: clear all KEL and TEL escrows * chore: version bump; logging fix --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- src/keri/app/cli/commands/escrow/__init__.py | 0 src/keri/app/cli/commands/escrow/clear.py | 57 +++++ src/keri/app/cli/commands/escrow/list.py | 219 +++++++++++++++++++ src/keri/app/cli/commands/migrate/run.py | 2 +- src/keri/app/cli/kli.py | 2 +- src/keri/db/basing.py | 168 ++++++++++++++ src/keri/db/dbing.py | 123 ++++++++++- src/keri/vdr/viring.py | 40 ++++ tests/app/cli/test_kli_commands.py | 28 ++- 13 files changed, 632 insertions(+), 15 deletions(-) create mode 100644 src/keri/app/cli/commands/escrow/__init__.py create mode 100644 src/keri/app/cli/commands/escrow/clear.py create mode 100644 src/keri/app/cli/commands/escrow/list.py diff --git a/Makefile b/Makefile index af46a7fff..23f2586ab 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.22 +VERSION=1.1.23 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 8c9bd01ed..367a4f1bf 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.22` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.23` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 72408885d..d8ad193c1 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.22', # also change in src/keri/__init__.py + version='1.1.23', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index e63adf6cb..99000ec16 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.22' # also change in setup.py +__version__ = '1.1.23' # also change in setup.py diff --git a/src/keri/app/cli/commands/escrow/__init__.py b/src/keri/app/cli/commands/escrow/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/keri/app/cli/commands/escrow/clear.py b/src/keri/app/cli/commands/escrow/clear.py new file mode 100644 index 000000000..e715a4427 --- /dev/null +++ b/src/keri/app/cli/commands/escrow/clear.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands.escrow module + +""" +import argparse + +from hio import help +from hio.base import doing +from keri.app.cli.common import existing +from keri.vdr import viring + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Clear escrows') +parser.set_defaults(handler=lambda args: handler(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran +parser.add_argument('--force', '-f', action="store_true", required=False, + help='True means perform clear without prompting the user') + + +def handler(args): + if not args.force: + print() + print("This command will clear all escrows and is not reversible.") + print() + yn = input("Are you sure you want to continue? [y|N]: ") + + if yn not in ("y", "Y"): + print("...exiting") + return [] + + kwa = dict(args=args) + return [doing.doify(clear, **kwa)] + + +def clear(tymth, tock=0.0, **opts): + """ Command line clear handler + """ + _ = (yield tock) + args = opts["args"] + name = args.name + base = args.base + bran = args.bran + logger.setLevel("INFO") + + with existing.existingHby(name=name, base=base, bran=bran) as hby: + hby.db.clearEscrows() + reger = viring.Reger(name=hby.name, db=hby.db, temp=False) + reger.clearEscrows() + diff --git a/src/keri/app/cli/commands/escrow/list.py b/src/keri/app/cli/commands/escrow/list.py new file mode 100644 index 000000000..06fe76617 --- /dev/null +++ b/src/keri/app/cli/commands/escrow/list.py @@ -0,0 +1,219 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands.escrow module + +""" +import argparse +import json + +from hio import help +from hio.base import doing + +from keri.core import eventing +from keri.app.cli.common import existing +from keri.db import dbing +from keri.kering import ConfigurationError +from keri.vdr import viring + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Views events in escrow state.') +parser.set_defaults(handler=lambda args: handler(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran + +parser.add_argument("--escrow", "-e", help="show values for one specific escrow", default=None) + + +def handler(args): + """ Command line escrow handler + + """ + kwa = dict(args=args) + return [doing.doify(escrows, **kwa)] + + +def escrows(tymth, tock=0.0, **opts): + _ = (yield tock) + + args = opts["args"] + name = args.name + base = args.base + bran = args.bran + escrow = args.escrow + + try: + with existing.existingHby(name=name, base=base, bran=bran) as hby: + escrows = dict() + + # KEL / Baser escrows + + if (not escrow) or escrow == "unverified-receipts": + escrows["unverified-receipts"] = sum(1 for key, _ in hby.db.getUreItemIter()) + + if (not escrow) or escrow == "verified-receipts": + escrows["verified-receipts"] = sum(1 for key, _ in hby.db.getVreItemIter()) + + if (not escrow) or escrow == "partially-signed-events": + pses = list() + key = ekey = b'' # both start same. when not same means escrows found + while True: # break when done + for ekey, edig in hby.db.getPseItemIter(key=key): + pre, sn = dbing.splitSnKey(ekey) # get pre and sn from escrow item + + try: + pses.append(eventing.loadEvent(hby.db, pre, edig)) + except ValueError as e: + raise e + + if ekey == key: # still same so no escrows found on last while iteration + break + key = ekey # setup next while iteration, with key after ekey + + escrows["partially-signed-events"] = pses + + if (not escrow) or escrow == "partially-witnessed-events": + pwes = list() + key = ekey = b'' # both start same. when not same means escrows found + while True: # break when done + for ekey, edig in hby.db.getPweItemIter(key=key): + pre, sn = dbing.splitSnKey(ekey) # get pre and sn from escrow item + + try: + pwes.append(eventing.loadEvent(hby.db, pre, edig)) + except ValueError as e: + raise e + + if ekey == key: # still same so no escrows found on last while iteration + break + key = ekey # setup next while iteration, with key after ekey + + escrows["partially-witnessed-events"] = pwes + + if (not escrow) or escrow == "unverified-event-indexed-couples": + escrows["unverified-event-indexed-couples"] = sum(1 for key, _ in hby.db.getUweItemIter()) + + if (not escrow) or escrow == "out-of-order-events": + oots = list() + key = ekey = b'' # both start same. when not same means escrows found + while True: + for ekey, edig in hby.db.getOoeItemIter(key=key): + pre, sn = dbing.splitSnKey(ekey) # get pre and sn from escrow item + + try: + oots.append(eventing.loadEvent(hby.db, pre, edig)) + except ValueError as e: + raise e + + if ekey == key: # still same so no escrows found on last while iteration + break + key = ekey # setup next while iteration, with key after ekey + + escrows["out-of-order-events"] = oots + + if (not escrow) or escrow == "likely-duplicitous-events": + ldes = list() + key = ekey = b'' # both start same. when not same means escrows found + while True: # break when done + for ekey, edig in hby.db.getLdeItemIter(key=key): + pre, sn = dbing.splitSnKey(ekey) # get pre and sn from escrow item + + try: + ldes.append(eventing.loadEvent(hby.db, pre, edig)) + except ValueError as e: + raise e + + if ekey == key: # still same so no escrows found on last while iteration + break + key = ekey # setup next while iteration, with key after ekey + + escrows["likely-duplicitous-events"] = ldes + + if (not escrow) or escrow == "query-not-found": + escrows["query-not-found"] = sum(1 for key, _ in hby.db.getQnfItemsNextIter()) + + if (not escrow) or escrow == "partially-delegated-events": + escrows["partially-delegated-events"] = sum(1 for key, _ in hby.db.getPdesItemsNextIter()) + + if (not escrow) or escrow == "reply": + escrows["reply"] = sum(1 for key, _ in hby.db.rpes.getItemIter()) + + if (not escrow) or escrow == "failed-oobi": + escrows["failed-oobi"] = sum(1 for key, _ in hby.db.eoobi.getItemIter()) + + if (not escrow) or escrow == 'group-partial-witness': + escrows["group-partial-witness"] = sum(1 for key, _ in hby.db.gpwe.getItemIter()) + + if (not escrow) or escrow == 'group-delegate': + escrows["group-delegate"] = sum(1 for key, _ in hby.db.gdee.getItemIter()) + + if (not escrow) or escrow == 'delegated-partial-witness': + escrows["delegated-partial-witness"] = sum(1 for key, _ in hby.db.dpwe.getItemIter()) + + if (not escrow) or escrow == 'group-partial-signed': + escrows["group-partial-signed"] = sum(1 for key, _ in hby.db.gpse.getItemIter()) + + if (not escrow) or escrow == 'exchange-partial-signed': + escrows["exchange-partial-signed"] = sum(1 for key, _ in hby.db.epse.getItemIter()) + + if (not escrow) or escrow == 'delegated-unanchored': + escrows["delegated-unanchored"] = sum(1 for key, _ in hby.db.dune.getItemIter()) + + # TEL / Reger escrows + reger = viring.Reger(name=hby.name, db=hby.db, temp=False) + + if (not escrow) or escrow == 'tel-out-of-order': + escrows["tel-out-of-order"] = sum(1 for key, _ in reger.getOotItemIter()) + + if (not escrow) or escrow == 'tel-partially-witnessed': + escrows["tel-partially-witnessed"] = sum(1 for key, _ in reger.getAllItemIter(reger.twes)) + + if (not escrow) or escrow == 'tel-anchorless': + escrows["tel-anchorless"] = sum(1 for key, _ in reger.getAllItemIter(reger.taes)) + + if (not escrow) or escrow == "missing-registry-escrow": + creds = list() + for (said,), dater in reger.mre.getItemIter(): + creder, *_ = reger.cloneCred(said) + creds.append(creder.sad) + + escrows["missing-registry-escrow"] = creds + + if (not escrow) or escrow == "broken-chain-escrow": + creds = list() + for (said,), dater in reger.mce.getItemIter(): + creder, *_ = reger.cloneCred(said) + creds.append(creder.sad) + + escrows["broken-chain-escrow"] = creds + + if (not escrow) or escrow == "missing-schema-escrow": + creds = list() + for (said,), dater in reger.mse.getItemIter(): + creder, *_ = reger.cloneCred(said) + creds.append(creder.sad) + + escrows["missing-schema-escrow"] = creds + + if (not escrow) or escrow == 'tel-missing-signature': + escrows["tel-missing-signature"] = sum(1 for key, _ in reger.cmse.getItemIter()) + + if (not escrow) or escrow == 'tel-partial-witness-escrow': + escrows["tel-partial-witness-escrow"] = sum(1 for key, _ in reger.tpwe.getItemIter()) + + if (not escrow) or escrow == 'tel-multisig': + escrows["tel-multisig"] = sum(1 for key, _ in reger.tmse.getItemIter()) + + if (not escrow) or escrow == 'tel-event-dissemination': + escrows["tel-event-dissemination"] = sum(1 for key, _ in reger.tede.getItemIter()) + + print(json.dumps(escrows, indent=2)) + + except ConfigurationError as e: + print(f"identifier prefix for {name} does not exist, incept must be run first", ) + return -1 diff --git a/src/keri/app/cli/commands/migrate/run.py b/src/keri/app/cli/commands/migrate/run.py index 499ed3ebb..de2a62eb4 100644 --- a/src/keri/app/cli/commands/migrate/run.py +++ b/src/keri/app/cli/commands/migrate/run.py @@ -11,7 +11,7 @@ from keri import kering from keri.db import basing -logger = help.ogler.getLogger("keri") +logger = help.ogler.getLogger() def handler(args): """ diff --git a/src/keri/app/cli/kli.py b/src/keri/app/cli/kli.py index a0bde194f..a3bd13631 100644 --- a/src/keri/app/cli/kli.py +++ b/src/keri/app/cli/kli.py @@ -4,7 +4,7 @@ """ import multicommand -from keri import help +from hio import help from keri.app import directing from keri.app.cli import commands diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index de29cefa1..a95fe9572 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -37,6 +37,7 @@ import keri from . import dbing, koming, subing +from .dbing import splitKey, dgKey from .. import kering from ..core import coring, eventing, parsing, serdering @@ -1155,6 +1156,80 @@ def migrate(self): self.version = keri.__version__ + def clearEscrows(self): + """ + Clear all escrows + """ + count = 0 + for (k, _) in self.getUreItemIter(): + count += 1 + self.delUres(key=k) + logger.info(f"KEL: Cleared {count} unverified receipt escrows") + + count = 0 + for (k, _) in self.getVreItemIter(): + count += 1 + self.delVres(key=k) + logger.info(f"KEL: Cleared {count} verified receipt escrows") + + count = 0 + for (k, _) in self.getPseItemIter(): + count += 1 + self.delPses(key=k) + logger.info(f"KEL: Cleared {count} partially signed escrows") + + count = 0 + for (k, _) in self.getPweItemIter(): + count += 1 + self.delPwes(key=k) + logger.info(f"KEL: Cleared {count} partially witnessed escrows") + + count = 0 + for (k, _) in self.getUweItemIter(): + count += 1 + self.delUwes(key=k) + logger.info(f"KEL: Cleared {count} unverified event indexed escrowed couples") + + count = 0 + for (k, _) in self.getOoeItemIter(): + count += 1 + self.delOoes(key=k) + logger.info(f"KEL: Cleared {count} out of order escrows") + + count = 0 + for (k, _) in self.getLdeItemIter(): + count += 1 + self.delLdes(key=k) + logger.info(f"KEL: Cleared {count} likely duplicitous escrows") + + count = 0 + for ekey, edig in self.getQnfItemsNextIter(): + count += 1 + pre, _ = splitKey(ekey) + self.delQnf(dgKey(pre, edig), edig) + logger.info(f"KEL: Cleared {count} query not found escrows") + + count = 0 + for (key, on, val) in self.getPdesItemsNextIter(): + count += 1 + self.delPde(key=key) + logger.info(f"KEL: Cleared {count} partially delegated key event escrows") + + for name, escrow, desc in [ + ('rpes', self.rpes, 'reply escrows'), + ('eoobi', self.eoobi, 'failed, retryable OOBI escrow'), + ('gpwe', self.gpwe, 'group partial witness escrow'), + ('gdee', self.gdee, 'group delegate escrow'), + ('dpwe', self.dpwe, 'delegated partial witness escrow'), + ('gpse', self.gpse, 'group partial signature escrow'), + ('epse', self.epse, 'exchange partial signature escrow'), + ('dune', self.dune, 'delegated unanchored escrow'),]: + count = 0 + for (k, _) in escrow.getItemIter(): + count += 1 + escrow.trim() + logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + @property def current(self): """ Current property determines if we are at the current database migration state. @@ -2139,6 +2214,20 @@ def getUreLast(self, key): """ return self.getIoValLast(self.ures, key) + def getUreItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of partial signed escrowed event triple items at next + key after key. + Items is (key, val) where proem has already been stripped from val + val is triple dig+pre+cig + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.ures, key) + def getUreItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2306,6 +2395,20 @@ def getVreLast(self, key): """ return self.getIoValLast(self.vres, key) + def getVreItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of partial signed escrowed event quintuple items at next + key after key. + Items is (key, val) where proem has already been stripped from val + val is Quinlet is edig + spre + ssnu + sdig +sig + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.vres, key) + def getVreItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2536,6 +2639,18 @@ def getPseLast(self, key): """ return self.getIoValLast(self.pses, key) + def getPseItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of partial signed escrowed event dig items at next key after key. + Items is (key, val) where proem has already been stripped from val + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.pses, key) + def getPseItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2670,6 +2785,18 @@ def getPweLast(self, key): """ return self.getIoValLast(self.pwes, key) + def getPweItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of partial witnessed escrowed event dig items at next key after key. + Items is (key, val) where proem has already been stripped from val + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.pwes, key) + def getPweItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2774,6 +2901,20 @@ def getUweLast(self, key): """ return self.getIoValLast(self.uwes, key) + def getUweItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of partial signed escrowed receipt couple items at next + key after key. + Items is (key, val) where proem has already been stripped from val + val is couple edig+wig + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.uwes, key) + def getUweItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2868,6 +3009,18 @@ def getOoeLast(self, key): """ return self.getIoValLast(self.ooes, key) + def getOoeItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of out of order escrowed event dig items at next key after key. + Items is (key, val) where proem has already been stripped from val + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.ooes, key) + def getOoeItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2983,6 +3136,9 @@ def getQnfItemsNextIter(self, key=b'', skip=True): """ return self.getIoItemsNextIter(self.qnfs, key, skip) + def getPdesItemsNextIter(self, key=b'', skip=True): + return self.getOnIoDupItemIter(self.pdes, key, skip) + def cntQnfs(self, key): """ Use snKey() @@ -3124,6 +3280,18 @@ def getLdeLast(self, key): """ return self.getIoValLast(self.ldes, key) + def getLdeItemIter(self, key=b''): + """ + Use sgKey() + Return iterator of likely duplicitous escrowed event dig items at next key after key. + Items is (key, val) where proem has already been stripped from val + If key is b'' empty then returns dup items at first key. + If skip is False and key is not b'' empty then returns dup items at key + Raises StopIteration Error when empty + Duplicates are retrieved in insertion order. + """ + return self.getTopIoDupItemIter(self.ldes, key) + def getLdeItemsNext(self, key=b'', skip=True): """ Use snKey() diff --git a/src/keri/db/dbing.py b/src/keri/db/dbing.py index 532fe8a7c..f32975943 100644 --- a/src/keri/db/dbing.py +++ b/src/keri/db/dbing.py @@ -82,7 +82,7 @@ def dgKey(pre, dig): return (b'%s.%s' % (pre, dig)) -def onKey(pre, sn): +def onKey(pre, sn, *, sep=b'.'): """ Returns bytes DB key from concatenation with '.' of qualified Base64 prefix bytes pre and int ordinal number of event, such as sequence number or first @@ -90,7 +90,7 @@ def onKey(pre, sn): """ if hasattr(pre, "encode"): pre = pre.encode("utf-8") # convert str to bytes - return (b'%s.%032x' % (pre, sn)) + return (b'%s%s%032x' % (pre, sep, sn)) snKey = onKey # alias so intent is clear, sn vs fn fnKey = onKey # alias so intent is clear, sn vs fn @@ -137,7 +137,7 @@ def splitKey(key, sep=b'.'): return tuple(splits) -def splitKeyON(key): +def splitKeyON(key, *, sep=b'.'): """ Returns list of pre and int on from key Accepts either bytes or str key @@ -145,9 +145,12 @@ def splitKeyON(key): """ if isinstance(key, memoryview): key = bytes(key) - pre, on = splitKey(key) + top, on = splitKey(key, sep=sep) on = int(on, 16) - return (pre, on) + return (top, on) + +splitSnKey = splitKeyON # alias so intent is clear, sn vs fn; backport of 1.2.x alias +splitFnKey = splitKeyON # alias so intent is clear, sn vs fn; backport of 1.2.x alias splitKeySN = splitKeyON # alias so intent is clear, sn vs fn splitKeyFN = splitKeyON # alias so intent is clear, sn vs fn @@ -662,6 +665,71 @@ def delTopVal(self, db, key=b''): ckey, cval = cursor.item() # cursor now at next item after deleted return result + # ported from OnIoDupSuber + def getOnIoDupItemIter(self, db, key=b'', on=0, *, sep=b'.'): + """ + Returns iterator of triples (key, on, val), at each key over all ordinal + numbered keys with same key + sep + on in db. Values are sorted by + onKey(key, on) where on is ordinal number int and key is prefix sans on. + Values duplicates are sorted internally by hidden prefixed insertion order + proem ordinal + Returned items are triples of (key, on, val) + when key is empty then retrieves whole db + + Raises StopIteration Error when empty. + + Returns: + items (Iterator[(key, on, val)]): triples of key, on, val + + Parameters: + db (subdb): named sub db in lmdb + key (bytes): key within sub db's keyspace plus trailing part on + when key is empty then retrieves whole db + on (int): ordinal number at which to initiate retrieval + sep (bytes): separator character for split + """ + for key, on, val in self.getOnItemIter(db=db, key=key, on=on, sep=sep): + val = val[33:] # strip proem + yield (key, on, val) + + # ported from OnSuberBase + def getOnItemIter(self, db, key=b'', on=0, *, sep=b'.'): + """ + Returns iterator of triples (key, on, val), at each key over all ordinal + numbered keys with same key + sep + on in db. Values are sorted by + onKey(key, on) where on is ordinal number int and key is prefix sans on. + Returned items are triples of (key, on, val) + When dupsort==true then duplicates are included in items since .iternext + includes duplicates. + when key is empty then retrieves whole db + + Raises StopIteration Error when empty. + + Returns: + items (Iterator[(key, on, val)]): triples of key, on, val with same + key but increments of on beginning with on + + Parameters: + db (subdb): named sub db in lmdb + key (bytes): key within sub db's keyspace plus trailing part on + when key is empty then retrieves whole db + on (int): ordinal number at which to initiate retrieval + sep (bytes): separator character for split + """ + with self.env.begin(db=db, write=False, buffers=True) as txn: + cursor = txn.cursor() + if key: # not empty + onkey = onKey(key, on, sep=sep) # start replay at this enty 0 is earliest + else: # empty + onkey = key + if not cursor.set_range(onkey): # moves to val at key >= onkey + return # no values end of db raises StopIteration + + for ckey, cval in cursor.iternext(): # get key, val at cursor + ckey, cn = splitKeyON(ckey, sep=sep) + if key and not ckey == key: + break + yield (ckey, cn, cval) # For subdbs with no duplicate values allowed at each key. (dupsort==False) # and use keys with ordinal as monotonically increasing number part @@ -1639,6 +1707,51 @@ def cntIoVals(self, db, key): " or wrong DUPFIXED size. ref) lmdb.BadValsizeError") return count + def getTopIoDupItemIter(self, db, top=b''): + """ + Iterates over top branch of db given by key of IoDup items where each value + has 33 byte insertion ordinal number proem (prefixed) with separator. + Automagically removes (strips) proem before returning items. + + Assumes DB opened with dupsort=True + + Returns: + items (abc.Iterator): iterator of (full key, val) tuples of all + dup items over a branch of the db given by top key where returned + full key is full database key for val not truncated top key. + Item is (key, val) with proem stripped from val stored in db. + If key = b'' then returns list of dup items for all keys in db. + + + Because cursor.iternext() advances cursor after returning item its safe + to delete the item within the iteration loop. curson.iternext() works + for both dupsort==False and dupsort==True + + Raises StopIteration Error when empty. + + Parameters: + db (lmdb._Database): instance of named sub db with dupsort==False + top (bytes): truncated top key, a key space prefix to get all the items + from multiple branches of the key space. If top key is + empty then gets all items in database + + Duplicates at a given key preserve insertion order of duplicate. + Because lmdb is lexocographic an insertion ordering proem is prepended to + all values that makes lexocographic order that same as insertion order. + + Duplicates are ordered as a pair of key plus value so prepending proem + to each value changes duplicate ordering. Proem is 33 characters long. + With 32 character hex string followed by '.' for essentiall unlimited + number of values which will be limited by memory. + + With prepended proem ordinal must explicity check for duplicate values + before insertion. Uses a python set for the duplicate inclusion test. + Set inclusion scales with O(1) whereas list inclusion scales with O(n). + """ + for top, val in self.getTopItemIter(db=db, key=top): + val = val[33:] # strip proem + yield (top, val) + def delIoVals(self, db, key): """ diff --git a/src/keri/vdr/viring.py b/src/keri/vdr/viring.py index 96eec603a..bafc2b749 100644 --- a/src/keri/vdr/viring.py +++ b/src/keri/vdr/viring.py @@ -22,6 +22,10 @@ from ..vc import proving from ..vdr import eventing +from hio import help + +logger = help.ogler.getLogger() + class rbdict(dict): """ Reger backed read through cache for registry state @@ -384,6 +388,42 @@ def reopen(self, **kwa): return self.env + def clearEscrows(self): + """Clear credential event escrows""" + # self.oots, self.twes, self.taes + count = 0 + for (k, _) in self.getOotItemIter(): + count += 1 + self.delOot(k) + logger.info(f"TEL: Cleared {count} out of order escrows.") + + count = 0 + for (k, ) in self.getAllItemIter(self.twes): + count += 1 + self.delTwe(k) + logger.info(f"TEL: Cleared {count} partially witnessed escrows.") + + count = 0 + for (k, _) in self.getAllItemIter(self.taes): + count += 1 + self.delTae(k) + logger.info(f"TEL: Cleared {count} anchorless escrows.") + + for name, sub, desc in [ + ( 'mre', self.mre, 'missing registry escrows'), + ( 'mce', self.mce, 'broken chain escrows'), + ( 'mse', self.mse, 'missing schema escrows'), + ('cmse', self.cmse, 'missing signature escrows'), + ('tpwe', self.tpwe, 'partial witness escrows'), + ('tmse', self.tmse, 'multisig escrows'), + ('tede', self.tede, 'event dissemination escrows'), + ]: + count = 0 + for (k, _) in sub.getItemIter(): + count += 1 + sub.trim() + logger.info(f"TEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + def cloneCreds(self, saids, db): """ Returns fully expanded credential with chained credentials attached. diff --git a/tests/app/cli/test_kli_commands.py b/tests/app/cli/test_kli_commands.py index 1fcfd566f..afb021102 100644 --- a/tests/app/cli/test_kli_commands.py +++ b/tests/app/cli/test_kli_commands.py @@ -233,19 +233,39 @@ def test_standalone_kli_commands(helpers, capsys): '\t3. DEMwUl3u8mJ-cWxSnReA0rQesIgZ8SFoHp0U2WyiZjRt\n' '\n') - args = parser.parse_args(["escrow", "--name", "test"]) + args = parser.parse_args(["escrow", "list", "--name", "test"]) assert args.handler is not None doers = args.handler(args) directing.runController(doers=doers) capesc = capsys.readouterr() assert capesc.out == ('{\n' - ' "out-of-order-events": [],\n' - ' "partially-witnessed-events": [],\n' + ' "unverified-receipts": 0,\n' + ' "verified-receipts": 0,\n' ' "partially-signed-events": [],\n' + ' "partially-witnessed-events": [],\n' + ' "unverified-event-indexed-couples": 0,\n' + ' "out-of-order-events": [],\n' ' "likely-duplicitous-events": [],\n' + ' "query-not-found": 0,\n' + ' "partially-delegated-events": 0,\n' + ' "reply": 0,\n' + ' "failed-oobi": 0,\n' + ' "group-partial-witness": 0,\n' + ' "group-delegate": 0,\n' + ' "delegated-partial-witness": 0,\n' + ' "group-partial-signed": 0,\n' + ' "exchange-partial-signed": 0,\n' + ' "delegated-unanchored": 0,\n' + ' "tel-out-of-order": 0,\n' + ' "tel-partially-witnessed": 0,\n' + ' "tel-anchorless": 0,\n' ' "missing-registry-escrow": [],\n' ' "broken-chain-escrow": [],\n' - ' "missing-schema-escrow": []\n' + ' "missing-schema-escrow": [],\n' + ' "tel-missing-signature": 0,\n' + ' "tel-partial-witness-escrow": 0,\n' + ' "tel-multisig": 0,\n' + ' "tel-event-dissemination": 0\n' '}\n') From 9a16f70efc3f9fdb22fbf90b309c717717b4f9db Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 25 Nov 2024 07:27:30 -0500 Subject: [PATCH 37/61] version bump Signed-off-by: Kevin Griffin --- src/keri/db/escrowing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keri/db/escrowing.py b/src/keri/db/escrowing.py index 03ea429ef..a2a886238 100644 --- a/src/keri/db/escrowing.py +++ b/src/keri/db/escrowing.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +1.1# -*- encoding: utf-8 -*- """ keri.core.escrowing module From 9884288df02bbd8d179c158527f77bc35a3832c0 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 25 Nov 2024 14:40:54 -0500 Subject: [PATCH 38/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 23f2586ab..05f47eb8e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.23 +VERSION=1.1.24 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 367a4f1bf..ffd6646ee 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.23` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.24` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index d8ad193c1..5a2487eb1 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.23', # also change in src/keri/__init__.py + version='1.1.24', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 99000ec16..eb5e29cee 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.23' # also change in setup.py +__version__ = '1.1.24' # also change in setup.py From d87ab628cfd07bef06db76bf7a84bce178c6be31 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 26 Nov 2024 07:05:42 -0500 Subject: [PATCH 39/61] trailing comma Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- src/keri/db/basing.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 05f47eb8e..2e10649fe 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.24 +VERSION=1.1.25 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index ffd6646ee..d488aca2b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.24` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.25` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 5a2487eb1..897fce190 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.24', # also change in src/keri/__init__.py + version='1.1.25', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index eb5e29cee..4f364a110 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.24' # also change in setup.py +__version__ = '1.1.25' # also change in setup.py diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index a95fe9572..c62db558d 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1223,7 +1223,7 @@ def clearEscrows(self): ('dpwe', self.dpwe, 'delegated partial witness escrow'), ('gpse', self.gpse, 'group partial signature escrow'), ('epse', self.epse, 'exchange partial signature escrow'), - ('dune', self.dune, 'delegated unanchored escrow'),]: + ('dune', self.dune, 'delegated unanchored escrow')]: count = 0 for (k, _) in escrow.getItemIter(): count += 1 From 8f5720b2b7168b06c1b4debb5645dbecb4f6f4f9 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 26 Nov 2024 07:35:20 -0500 Subject: [PATCH 40/61] change log Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- src/keri/db/basing.py | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 2e10649fe..a1b599bad 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.25 +VERSION=1.1.26 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index d488aca2b..414caf21b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.25` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.26` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 897fce190..62472a123 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.25', # also change in src/keri/__init__.py + version='1.1.26', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 4f364a110..acf6b830c 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.25' # also change in setup.py +__version__ = '1.1.26' # also change in setup.py diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index c62db558d..e119b9edf 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1228,7 +1228,8 @@ def clearEscrows(self): for (k, _) in escrow.getItemIter(): count += 1 escrow.trim() - logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + # logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + logger.info(f"Cleared all escrows") @property def current(self): From d75004030df41045e2299c4eb22cdf5d7359e076 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Wed, 27 Nov 2024 11:25:55 -0500 Subject: [PATCH 41/61] escrow logs Signed-off-by: Kevin Griffin --- src/keri/db/basing.py | 7 ++----- src/keri/vdr/viring.py | 8 +++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index e119b9edf..74c1951e2 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1224,12 +1224,9 @@ def clearEscrows(self): ('gpse', self.gpse, 'group partial signature escrow'), ('epse', self.epse, 'exchange partial signature escrow'), ('dune', self.dune, 'delegated unanchored escrow')]: - count = 0 - for (k, _) in escrow.getItemIter(): - count += 1 escrow.trim() - # logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") - logger.info(f"Cleared all escrows") + logger.info(f"KEL: Cleared escrow ({name.ljust(5)}): {desc}") + logger.info("Cleared KEL escrows") @property def current(self): diff --git a/src/keri/vdr/viring.py b/src/keri/vdr/viring.py index bafc2b749..409b510c2 100644 --- a/src/keri/vdr/viring.py +++ b/src/keri/vdr/viring.py @@ -416,13 +416,11 @@ def clearEscrows(self): ('cmse', self.cmse, 'missing signature escrows'), ('tpwe', self.tpwe, 'partial witness escrows'), ('tmse', self.tmse, 'multisig escrows'), - ('tede', self.tede, 'event dissemination escrows'), + ('tede', self.tede, 'event dissemination escrows') ]: - count = 0 - for (k, _) in sub.getItemIter(): - count += 1 sub.trim() - logger.info(f"TEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + logger.info(f"TEL: Cleared escrow ({name.ljust(5)}): {desc}") + logger.info("Cleared TEL escrows") def cloneCreds(self, saids, db): """ Returns fully expanded credential with chained credentials attached. From 22bae1e0d6df8f65cb1d74e7433f549f2b1bb1ab Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 3 Dec 2024 12:28:01 -0500 Subject: [PATCH 42/61] adds test for escrow clear Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/escrow.py | 159 ----------------------- src/keri/app/cli/commands/escrow/list.py | 2 +- src/keri/db/basing.py | 48 +++---- tests/db/test_basing.py | 73 ++++++++++- 4 files changed, 99 insertions(+), 183 deletions(-) delete mode 100644 src/keri/app/cli/commands/escrow.py diff --git a/src/keri/app/cli/commands/escrow.py b/src/keri/app/cli/commands/escrow.py deleted file mode 100644 index 24d78f335..000000000 --- a/src/keri/app/cli/commands/escrow.py +++ /dev/null @@ -1,159 +0,0 @@ -# -*- encoding: utf-8 -*- -""" -KERI -keri.kli.commands module - -""" -import argparse -import json - -from hio import help -from hio.base import doing - -from keri.core import eventing -from keri.app.cli.common import existing -from keri.db import dbing -from keri.kering import ConfigurationError -from keri.vdr import viring - -logger = help.ogler.getLogger() - -parser = argparse.ArgumentParser(description='Initialize a prefix') -parser.set_defaults(handler=lambda args: handler(args), - transferable=True) -parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) -parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', - required=False, default="") -parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', - dest="bran", default=None) # passcode => bran - -parser.add_argument("--escrow", "-e", help="show values for one specific escrow", default=None) - - -def handler(args): - """ Command line escrow handler - - """ - kwa = dict(args=args) - return [doing.doify(escrows, **kwa)] - - -def escrows(tymth, tock=0.0, **opts): - _ = (yield tock) - - args = opts["args"] - name = args.name - base = args.base - bran = args.bran - escrow = args.escrow - - try: - with existing.existingHby(name=name, base=base, bran=bran) as hby: - reger = viring.Reger(name=hby.name, db=hby.db, temp=False) - - escrows = dict() - if (not escrow) or escrow == "out-of-order-events": - oots = list() - key = ekey = b'' # both start same. when not same means escrows found - while True: - for ekey, edig in hby.db.getOoeItemsNextIter(key=key): - pre, sn = dbing.splitKeySN(ekey) # get pre and sn from escrow item - - try: - oots.append(eventing.loadEvent(hby.db, pre, edig)) - except ValueError as e: - raise e - - if ekey == key: # still same so no escrows found on last while iteration - break - key = ekey # setup next while iteration, with key after ekey - - escrows["out-of-order-events"] = oots - - if (not escrow) or escrow == "partially-witnessed-events": - pwes = list() - key = ekey = b'' # both start same. when not same means escrows found - while True: # break when done - for ekey, edig in hby.db.getPweItemsNextIter(key=key): - pre, sn = dbing.splitKeySN(ekey) # get pre and sn from escrow item - - try: - pwes.append(eventing.loadEvent(hby.db, pre, edig)) - except ValueError as e: - raise e - - if ekey == key: # still same so no escrows found on last while iteration - break - key = ekey # setup next while iteration, with key after ekey - - escrows["partially-witnessed-events"] = pwes - - if (not escrow) or escrow == "partially-signed-events": - pses = list() - key = ekey = b'' # both start same. when not same means escrows found - while True: # break when done - for ekey, edig in hby.db.getPseItemsNextIter(key=key): - pre, sn = dbing.splitKeySN(ekey) # get pre and sn from escrow item - - try: - pses.append(eventing.loadEvent(hby.db, pre, edig)) - except ValueError as e: - raise e - - if ekey == key: # still same so no escrows found on last while iteration - break - key = ekey # setup next while iteration, with key after ekey - - escrows["partially-signed-events"] = pses - - if (not escrow) or escrow == "likely-duplicitous-events": - ldes = list() - key = ekey = b'' # both start same. when not same means escrows found - while True: # break when done - for ekey, edig in hby.db.getLdeItemsNextIter(key=key): - pre, sn = dbing.splitKeySN(ekey) # get pre and sn from escrow item - - try: - ldes.append(eventing.loadEvent(hby.db, pre, edig)) - except ValueError as e: - raise e - - if ekey == key: # still same so no escrows found on last while iteration - break - key = ekey # setup next while iteration, with key after ekey - - escrows["likely-duplicitous-events"] = ldes - - if (not escrow) or escrow == "missing-registry-escrow": - creds = list() - for (said,), dater in reger.mre.getItemIter(): - creder, *_ = reger.cloneCred(said) - creds.append(creder.sad) - - escrows["missing-registry-escrow"] = creds - - if (not escrow) or escrow == "broken-chain-escrow": - creds = list() - for (said,), dater in reger.mce.getItemIter(): - creder, *_ = reger.cloneCred(said) - creds.append(creder.sad) - - escrows["broken-chain-escrow"] = creds - - if (not escrow) or escrow == "missing-schema-escrow": - creds = list() - for (said,), dater in reger.mse.getItemIter(): - creder, *_ = reger.cloneCred(said) - creds.append(creder.sad) - - escrows["missing-schema-escrow"] = creds - - print(json.dumps(escrows, indent=2)) - - if not(escrow) or escrow == 'tel-partial-witness-escrow': - for (regk, snq), (prefixer, seqner, saider) in reger.tpwe.getItemIter(): - pass - - except ConfigurationError as e: - print(f"identifier prefix for {name} does not exist, incept must be run first", ) - return -1 diff --git a/src/keri/app/cli/commands/escrow/list.py b/src/keri/app/cli/commands/escrow/list.py index 06fe76617..9e3178569 100644 --- a/src/keri/app/cli/commands/escrow/list.py +++ b/src/keri/app/cli/commands/escrow/list.py @@ -63,7 +63,7 @@ def escrows(tymth, tock=0.0, **opts): pses = list() key = ekey = b'' # both start same. when not same means escrows found while True: # break when done - for ekey, edig in hby.db.getPseItemIter(key=key): + for ekey, edig in hby.db.getPseItemsNextIter(key=key): pre, sn = dbing.splitSnKey(ekey) # get pre and sn from escrow item try: diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index 74c1951e2..eddb93047 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1173,7 +1173,7 @@ def clearEscrows(self): logger.info(f"KEL: Cleared {count} verified receipt escrows") count = 0 - for (k, _) in self.getPseItemIter(): + for (k, _) in self.getPseItemsNextIter(): count += 1 self.delPses(key=k) logger.info(f"KEL: Cleared {count} partially signed escrows") @@ -1203,14 +1203,12 @@ def clearEscrows(self): logger.info(f"KEL: Cleared {count} likely duplicitous escrows") count = 0 - for ekey, edig in self.getQnfItemsNextIter(): - count += 1 - pre, _ = splitKey(ekey) - self.delQnf(dgKey(pre, edig), edig) + for k, _ in self.getQnfItemsNextIter(): + self.delQnfs(key=k) logger.info(f"KEL: Cleared {count} query not found escrows") count = 0 - for (key, on, val) in self.getPdesItemsNextIter(): + for (key, _) in self.getPdeItemsNextIter(): count += 1 self.delPde(key=key) logger.info(f"KEL: Cleared {count} partially delegated key event escrows") @@ -1224,8 +1222,11 @@ def clearEscrows(self): ('gpse', self.gpse, 'group partial signature escrow'), ('epse', self.epse, 'exchange partial signature escrow'), ('dune', self.dune, 'delegated unanchored escrow')]: + count = 0 + for (k, _) in escrow.getItemIter(): + count += 1 escrow.trim() - logger.info(f"KEL: Cleared escrow ({name.ljust(5)}): {desc}") + logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") logger.info("Cleared KEL escrows") @property @@ -2637,18 +2638,6 @@ def getPseLast(self, key): """ return self.getIoValLast(self.pses, key) - def getPseItemIter(self, key=b''): - """ - Use sgKey() - Return iterator of partial signed escrowed event dig items at next key after key. - Items is (key, val) where proem has already been stripped from val - If key is b'' empty then returns dup items at first key. - If skip is False and key is not b'' empty then returns dup items at key - Raises StopIteration Error when empty - Duplicates are retrieved in insertion order. - """ - return self.getTopIoDupItemIter(self.pses, key) - def getPseItemsNext(self, key=b'', skip=True): """ Use snKey() @@ -2728,6 +2717,24 @@ def getPde(self, key): """ return self.getVal(self.pdes, key) + def getPdes(self, key): + """ + Use dgKey() + Return list of out of order escrow event dig vals at key + Returns empty list if no entry at key + Duplicates are retrieved in insertion order. + """ + return self.getIoVals(self.pdes, key) + + def getPdeItemsNextIter(self, key=b'', skip=True): + """ + Use dgKey() + Return list of witnessed signed escrowed event dig vals at key + Returns empty list if no entry at key + Duplicates are retrieved in insertion order. + """ + return self.getIoItemsNextIter(self.pdes, key, skip) + def delPde(self, key): """ Use dgKey() @@ -3134,9 +3141,6 @@ def getQnfItemsNextIter(self, key=b'', skip=True): """ return self.getIoItemsNextIter(self.qnfs, key, skip) - def getPdesItemsNextIter(self, key=b'', skip=True): - return self.getOnIoDupItemIter(self.pdes, key, skip) - def cntQnfs(self, key): """ Use snKey() diff --git a/tests/db/test_basing.py b/tests/db/test_basing.py index b067985dc..df04d7345 100644 --- a/tests/db/test_basing.py +++ b/tests/db/test_basing.py @@ -11,6 +11,7 @@ import pytest from hio.base import doing +from keri.core.serdering import Serder from tests.app import openMultiSig from keri.kering import Versionage from keri.app import habbing @@ -21,7 +22,7 @@ from keri.core.eventing import incept, rotate, interact, Kever from keri.db import basing from keri.db import dbing -from keri.db.basing import openDB, Baser, KeyStateRecord +from keri.db.basing import openDB, Baser, KeyStateRecord, OobiRecord from keri.db.dbing import (dgKey, onKey, snKey) from keri.db.dbing import openLMDB from keri.help.helping import datify, dictify @@ -2274,6 +2275,76 @@ def test_group_members(): """End Test""" +def test_clear_escrows(): + with openDB() as db: + key = b'A.a' + vals = [b"z", b"m", b"x", b"a"] + + db.putUres(key, vals) + db.putVres(key, vals) + db.putPses(key, vals) + db.putPwes(key, vals) + db.putUwes(key, vals) + db.putOoes(key, vals) + db.putLdes(key, vals) + db.putQnfs(key, vals) + + preb = 'DAzwEHHzq7K0gzQPYGGwTmuupUhPx5_yZ-Wk1x4ejhcc'.encode("utf-8") + digb = 'EGAPkzNZMtX-QiVgbRbyAIZGoXvbGv9IPb0foWTZvI_4'.encode("utf-8") + key = dgKey(preb, digb) + ssnu1 = b'0AAAAAAAAAAAAAAAAAAAAAAB' + sdig1 = b'EALkveIFUPvt38xhtgYYJRCCpAGO7WjjHVR37Pawv67E' + val1 = ssnu1 + sdig1 + + db.putPde(key, val1) + + pre = 'k' + saider = coring.Saider(qb64b='EGAPkzNZMtX-QiVgbRbyAIZGoXvbGv9IPb0foWTZvI_4') + db.rpes.put(keys=('route',), vals=[saider]) + assert db.rpes.cnt(keys=('route',)) == 1 + + db.eoobi.pin(keys=('url',), val=OobiRecord()) + assert db.eoobi.cntAll() == 1 + + db.gpwe.add(keys=(pre,), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) + assert db.gpwe.cnt(keys=(pre,)) == 1 + + db.gdee.add(keys=(pre,), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) + assert db.gdee.cnt(keys=(pre,)) == 1 + + serder = Serder(raw=b'{"v":"KERI10JSON0000cb_","t":"ixn","d":"EG8WAmM29ZBdoXbnb87yiPxQw4Y7gcQjqZS74vBAKsRm","i":"DApYGFaqnrALTyejaJaGAVhNpSCtqyerPqWVK9ZBNZk0","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","a":[]}') + db.dpwe.pin(keys=(pre, 'said'), val=serder) + assert db.dpwe.get(keys=(pre, 'said')) is not None + + db.gpse.add(keys=('qb64',), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) + assert db.gpse.cnt(keys=('qb64',)) == 1 + + db.epse.put(keys=('dig',), val=serder) + assert db.epse.get(keys=('dig',)) is not None + + db.dune.pin(keys=(pre, 'said'), val=serder) + assert db.dune.get(keys=(pre, 'said')) is not None + + db.clearEscrows() + + assert db.getUres(key) == [] + assert db.getVres(key) == [] + assert db.getPses(key) == [] + assert db.getPwes(key) == [] + assert db.getUwes(key) == [] + assert db.getOoes(key) == [] + assert db.getLdes(key) == [] + assert db.getQnfs(key) == [] + assert db.getPdes(key) == [] + assert db.rpes.cnt(keys=('route',)) == 0 + assert db.eoobi.cntAll() == 0 + assert db.gpwe.cnt(keys=(pre,)) == 0 + assert db.gdee.cnt(keys=(pre,)) == 0 + assert db.dpwe.get(keys=(pre, 'said')) is None + assert db.gpse.cnt(keys=('qb64',)) == 0 + assert db.epse.get(keys=('dig',)) is None + assert db.dune.get(keys=(pre, 'said')) is None + if __name__ == "__main__": test_baser() test_clean_baser() From a700ce6aa6681fde8e51956e35499ea8d01123c4 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Fri, 13 Dec 2024 16:06:45 -0500 Subject: [PATCH 43/61] adds rp to exn to work with newer witnesses running on newer keri (#905) Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/escrow/list.py | 2 +- src/keri/core/serdering.py | 4 +- src/keri/peer/exchanging.py | 1 + tests/app/test_delegating.py | 16 +-- tests/app/test_grouping.py | 44 +++--- tests/app/test_oobiing.py | 24 ++-- tests/core/test_serdering.py | 16 +-- tests/peer/test_exchanging.py | 106 +++++++------- tests/vc/test_protocoling.py | 173 +++++++++++++---------- 9 files changed, 196 insertions(+), 190 deletions(-) diff --git a/src/keri/app/cli/commands/escrow/list.py b/src/keri/app/cli/commands/escrow/list.py index 9e3178569..4e647c3d9 100644 --- a/src/keri/app/cli/commands/escrow/list.py +++ b/src/keri/app/cli/commands/escrow/list.py @@ -138,7 +138,7 @@ def escrows(tymth, tock=0.0, **opts): escrows["query-not-found"] = sum(1 for key, _ in hby.db.getQnfItemsNextIter()) if (not escrow) or escrow == "partially-delegated-events": - escrows["partially-delegated-events"] = sum(1 for key, _ in hby.db.getPdesItemsNextIter()) + escrows["partially-delegated-events"] = sum(1 for key, _ in hby.db.getPdeItemsNextIter()) if (not escrow) or escrow == "reply": escrows["reply"] = sum(1 for key, _ in hby.db.rpes.getItemIter()) diff --git a/src/keri/core/serdering.py b/src/keri/core/serdering.py index a6a464e0f..2c271a74c 100644 --- a/src/keri/core/serdering.py +++ b/src/keri/core/serdering.py @@ -248,7 +248,7 @@ class Serder: Ilks.bar: Fieldage(saids={Saids.d: DigDex.Blake3_256}, alls=dict(v='', t='',d='', dt='', r='',a=[])), Ilks.exn: Fieldage(saids={Saids.d: DigDex.Blake3_256}, - alls=dict(v='', t='', d='', i="", p="", dt='', r='',q={}, + alls=dict(v='', t='', d='', i="", rp='', p="", dt='', r='',q={}, a=[], e={})), Ilks.vcp: Fieldage(saids={Saids.d: DigDex.Blake3_256, Saids.i: DigDex.Blake3_256,}, @@ -304,7 +304,7 @@ class Serder: Ilks.bar: Fieldage(saids={Saids.d: DigDex.Blake3_256}, alls=dict(v='', t='',d='', i='', dt='', r='',a=[])), Ilks.exn: Fieldage(saids={Saids.d: DigDex.Blake3_256}, - alls=dict(v='', t='', d='', i="", p="", dt='', r='', q={}, + alls=dict(v='', t='', d='', i="", rp="", p="", dt='', r='', q={}, a=[], e={})), }, }, diff --git a/src/keri/peer/exchanging.py b/src/keri/peer/exchanging.py index fc1b3c234..0ab215956 100644 --- a/src/keri/peer/exchanging.py +++ b/src/keri/peer/exchanging.py @@ -338,6 +338,7 @@ def exchange(route, t=ilk, d="", i=sender, + rp="", p=p, dt=dt, r=route, diff --git a/tests/app/test_delegating.py b/tests/app/test_delegating.py index 7742a1d2b..f72659036 100644 --- a/tests/app/test_delegating.py +++ b/tests/app/test_delegating.py @@ -124,17 +124,15 @@ def test_delegation_request(mockHelpingNowUTC): evt = hab.endorse(serder=serder) exn, atc = delegating.delegateRequestExn(hab=hab, delpre=delpre, evt=evt) - assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAADECnBl' - b'0c14SVi7Keh__sd1PVhinSy-itPr33ZxvSjJYFastqXw9ZTFGNKsY6iALUk5xP3S' - b'399tJrPFe7PtuNAN') + assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg' + b'-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3' + b'-AABAACzeUyP6__0oDca-Oiv2iGXKghBw_8sI4ZHyyeMedvz0iZIIQYqJd2Zt7cDHRh7xBGWI85J_oOixLET3mFZUu0A') assert exn.ked["r"] == '/delegate/request' - assert exn.saidb == b'EOiDc2wEmhHc7sbLG64y2gveCIRlFe4BuISaz0mlOuZz' - assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAADECnBl' - b'0c14SVi7Keh__sd1PVhinSy-itPr33ZxvSjJYFastqXw9ZTFGNKsY6iALUk5xP3S' - b'399tJrPFe7PtuNAN') + assert exn.saidb == b'EHPkcmdLGql9_1WD0wl0OalYk8PcF4HMMd7gGi-iqfSe' + assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg' + b'-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3' + b'-AABAACzeUyP6__0oDca-Oiv2iGXKghBw_8sI4ZHyyeMedvz0iZIIQYqJd2Zt7cDHRh7xBGWI85J_oOixLET3mFZUu0A') data = exn.ked["a"] assert data["delpre"] == delpre embeds = exn.ked['e'] diff --git a/tests/app/test_grouping.py b/tests/app/test_grouping.py index 2bfcf3e35..6141a0562 100644 --- a/tests/app/test_grouping.py +++ b/tests/app/test_grouping.py @@ -638,12 +638,11 @@ def test_multisig_incept(mockHelpingNowUTC): icp=hab.makeOwnEvent(sn=hab.kever.sn)) assert exn.ked["r"] == '/multisig/icp' - assert exn.saidb == b'EGDEBUZW--n-GqOOwRflzBeqoQsYWKMOQVU_1YglG-BL' - assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAAC84-o2' - b'HKwKxhL1ttzykB9zuFaGV6OpQ05b1ZJYAeBFrR7kVON1aNjpLgQCG_0bY4FUiP7F' - b'GTVDrBjuFhbeDKAH-LAa5AACAA-e-icp-AABAACihaKoLnoXxRoxGbFfOy67YSh6' - b'UxtgjT2oxupnLDz2FlhevGJKTMObbdex9f0Hqob6uTavSJvsXf5RzitskkkC') + assert exn.saidb == b'EJ6Kl50IBicAa8zND_3wMSQ5itw555V7NKid9y1SKobe' + assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg' + b'-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3' + b'-AABAACL4cf7LxzKJgaJbb7wWHLuTfj3wManDV0SW7euFNZDiEhD1kUiP3_wtOIfqB_ZsEceE4oIgOOZwFROyrcf9ScB' + b'-LAa5AACAA-e-icp-AABAACihaKoLnoXxRoxGbFfOy67YSh6UxtgjT2oxupnLDz2FlhevGJKTMObbdex9f0Hqob6uTavSJvsXf5RzitskkkC') data = exn.ked["a"] assert data["smids"] == aids assert "icp" in exn.ked['e'] @@ -662,11 +661,10 @@ def test_multisig_rotate(mockHelpingNowUTC): exn, atc = grouping.multisigRotateExn(ghab=ghab1, smids=ghab1.smids, rmids=ghab1.rmids, rot=rot) assert exn.ked["r"] == '/multisig/rot' - assert exn.saidb == b'ENfCk9DUUck6Ixe6cYnbCbJfIsisA3H4kHPwm5Z-2Tf8' - assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAA' - b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAADChiAf' - b'iExAQ2ETkzzf7MOubXV9mL-r6fPsOI4yn348yeE5dXqdI7ddn5-wnPwNVjqqKkDp' - b'xlOEFYRiBQEbwZQC') + assert exn.saidb == b'EC2IKkvJh6_Ukx-ZWP20qyHPWpXYfZdCQkydA9HwYE9c' + assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAAAAAAAAAAEH__mobl7NDyyQCB1DoLK' + b'-OPSueraPtZAlWEjfOYkaba-AABAABxikcUcQLQyCuOfQXYBeyFd3hzMaaZ_wHV_KPPX8DyFcold4P8mdGC' + b'-meFY9P7qoJd3lPA1khblmqY5jhK2kAL') data = exn.ked["a"] assert data["smids"] == ghab1.smids @@ -775,12 +773,12 @@ def test_multisig_interact(mockHelpingNowUTC): ixn=ixn) assert exn.ked["r"] == '/multisig/ixn' - assert exn.saidb == b'EGQ_DqGlSBx2MKJfHr6liXAngFpQ0UCtV1cdVMUtJHdN' - assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAA' - b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAAB3yX6b' - b'EXb8N63PKaMaFqijZVT5TqVtoO8q1BFnoJW3rDkNuJ9lEMpEN-44HKGtvniWZ6-d' - b'CVPS4fsEXKZAKGkB-LAa5AACAA-e-ixn-AABAABG58m7gibjdrQ8YU-8WQ8A70nc' - b'tYekYr3xdfZ5WgDQOD0bb9pI7SuuaJvzfAQisLAYQnztA82pAo1Skhf1vQwD') + assert exn.saidb == b'EDF8o6SK-s2jxUVnlGtqAVtXTF-wyZ26c0dUsS5p766q' + assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAAAAAAAAAAEH__mobl7NDyyQCB1DoLK' + b'-OPSueraPtZAlWEjfOYkaba' + b'-AABAABFfU5so86inNogCPN7Ko8WXvkMKeiUKPScQ3FYrVmngNpVmW8xmhOTfixuWFlLcQPjEf3bRQhvNvx7azcI_vwB' + b'-LAa5AACAA-e-ixn-AABAABG58m7gibjdrQ8YU' + b'-8WQ8A70nctYekYr3xdfZ5WgDQOD0bb9pI7SuuaJvzfAQisLAYQnztA82pAo1Skhf1vQwD') data = exn.ked["a"] assert data["smids"] == ghab1.smids assert data["gid"] == ghab1.pre @@ -795,12 +793,12 @@ def test_multisig_registry_incept(mockHelpingNowUTC, mockCoringRandomNonce): usage="Issue vLEI Credentials") assert exn.ked["r"] == '/multisig/vcp' - assert exn.saidb == b'ECKiNFo7fpG4vS5tUeja3EvOqT8ctq4AW8E3HKsP7dJo' - assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAA' - b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAABh6d0m' - b'lebT57L8o2si7DfEvPCoXJP0ekPiBqkzQns3-P7dz36MPXhjNFW6xRRdUstDLAZe' - b'BEqBxBCltMpTZGsD-LAa5AACAA-e-anc-AABAAD2mK9ICW9x1-0NZGkEDOcAbZ58' - b'VWK9LOTwyN2lSfHr2zY638P1SBStoh8mjgy7nOTGMyujOXMKvF_ZDeQ_ISYA') + assert exn.saidb == b'ELTlVFjqhqLkGBqItC9P6RADjranADW8FwD7nnz5ngwO' + assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAAAAAAAAAAEH__mobl7NDyyQCB1DoLK' + b'-OPSueraPtZAlWEjfOYkaba' + b'-AABAABY2UZSi_FQRViWfk_wdBmbgPUus1PtJzBPUDpfKEYvhHhsT6IB7z3IswPlrwUc0rTwjN1ON9ssFoTtTlMJqG8K' + b'-LAa5AACAA-e-anc-AABAAD2mK9ICW9x1' + b'-0NZGkEDOcAbZ58VWK9LOTwyN2lSfHr2zY638P1SBStoh8mjgy7nOTGMyujOXMKvF_ZDeQ_ISYA') data = exn.ked["a"] assert data == {'gid': 'EERn_laF0qwP8zTBGL86LbF84J0Yh2IvQSRskH3BZZiy', 'usage': 'Issue vLEI Credentials'} diff --git a/tests/app/test_oobiing.py b/tests/app/test_oobiing.py index fbd92f2f4..4963e1e8a 100644 --- a/tests/app/test_oobiing.py +++ b/tests/app/test_oobiing.py @@ -55,21 +55,21 @@ def test_oobi_share(mockHelpingNowUTC): exn, atc = oobiing.oobiRequestExn(hab=hab, dest="EO2kxXW0jifQmuPevqg6Zpi3vE-WYoj65i_XhpruWtOg", oobi="http://127.0.0.1/oobi") - assert exn.ked == {'a': {'dest': 'EO2kxXW0jifQmuPevqg6Zpi3vE-WYoj65i_XhpruWtOg', - 'oobi': 'http://127.0.0.1/oobi'}, - 'd': 'EMAhEMPbBU2B-Ha-yLxMEZk49KHYkzZgMv9aZS8gDl1m', - 'dt': '2021-01-01T00:00:00.000000+00:00', - 'e': {}, + assert exn.ked == {'v': 'KERI10JSON000136_', 't': 'exn', 'd': 'EII7EvdWFqv0jkjRv10t01zAUcRYbjVhZ_yo3VPZEbpS', 'i': 'EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3', + 'rp': '', 'p': '', - 'q': {}, + 'dt': '2021-01-01T00:00:00.000000+00:00', 'r': '/oobis', - 't': 'exn', - 'v': 'KERI10JSON00012e_'} - assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAACsgmsu' - b'VJoY5a7vicZQ7pT_MZqCe-0psgReRxyoBfFaAPxZ7Vss2eteFuvwDWBeyKc1B-yc' - b'p-2QZzIZJ94_9hIP') + 'q': {}, + 'a': { + 'dest': 'EO2kxXW0jifQmuPevqg6Zpi3vE-WYoj65i_XhpruWtOg', + 'oobi': 'http://127.0.0.1/oobi'}, + 'e': {} + } + assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg' + b'-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3' + b'-AABAABdw3eSw_7BW2o3z1ufxxs1CPgX1TgtJzn-MxvMjLYTidUd8KSxNKbPU9M3A4orYJDMGMIzhabHJmKA4ZIGbcgK') def test_oobiery(): diff --git a/tests/core/test_serdering.py b/tests/core/test_serdering.py index fde03b557..29eabf379 100644 --- a/tests/core/test_serdering.py +++ b/tests/core/test_serdering.py @@ -39,7 +39,7 @@ def test_serder(): 'rpy': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'dt': '', 'r': '', 'a': []}), 'pro': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'dt': '', 'r': '', 'rr': '', 'q': {}}), 'bar': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'dt': '', 'r': '', 'a': []}), - 'exn': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'p': '', 'dt': '', 'r': '', 'q': {}, 'a': [], 'e': {}}), + 'exn': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'rp': '', 'p': '', 'dt': '', 'r': '', 'q': {}, 'a': [], 'e': {}}), 'vcp': Fieldage(saids={'d': 'E', 'i': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'ii': '', 's': '0', 'c': [], 'bt': '0', 'b': [], 'n': ''}), 'vrt': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'p': '', 's': '0', 'bt': '0', 'br': [], 'ba': []}), 'iss': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 's': '0', 'ri': '', 'dt': ''}), @@ -56,7 +56,7 @@ def test_serder(): 'rpy': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'dt': '', 'r': '', 'a': []}), 'pro': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'dt': '', 'r': '', 'rr': '', 'q': {}}), 'bar': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'dt': '', 'r': '', 'a': []}), - 'exn': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'p': '', 'dt': '', 'r': '', 'q': {}, 'a': [], 'e': {}})}}, + 'exn': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'rp': '', 'p': '', 'dt': '', 'r': '', 'q': {}, 'a': [], 'e': {}})}}, 'CREL': {Versionage(major=1, minor=1): {'vcp': Fieldage(saids={'d': 'E', 'i': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'ii': '', 's': '0', 'c': [], 'bt': '0', 'b': [], 'u': ''}), 'vrt': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 'p': '', 's': '0', 'bt': '0', 'br': [], 'ba': []}), 'iss': Fieldage(saids={'d': 'E'}, alls={'v': '', 't': '', 'd': '', 'i': '', 's': '0', 'ri': '', 'dt': ''}), @@ -2092,10 +2092,11 @@ def test_serderkeri_exn(): # Test KERI JSON with makify defaults for self bootstrap with ilk ixn serder = SerderKERI(makify=True, ilk=kering.Ilks.exn) # make with defaults - assert serder.sad == {'v': 'KERI10JSON000088_', + assert serder.sad == {'v': 'KERI10JSON000090_', 't': 'exn', - 'd': 'EMuAoRSE4zREKKYyvuNeYCDM9_MwPQIh1WL0cFC4e-bU', + 'd': 'EPx9pShQTfv2FoISZJAZ4dlUcekG8-CSkgJh0i0q_iJn', 'i': '', + 'rp': '', 'p': '', 'dt': '', 'r': '', @@ -2103,11 +2104,8 @@ def test_serderkeri_exn(): 'a': [], 'e': {}} - assert serder.raw == (b'{"v":"KERI10JSON000088_","t":"exn",' - b'"d":"EMuAoRSE4zREKKYyvuNeYCDM9_MwPQIh1WL0' - b'cFC4e-bU","i":"","p":"","dt":"","r":"","q":{},"a":[],"e":{}}') - - + assert serder.raw == (b'{"v":"KERI10JSON000090_","t":"exn","d":"EPx9pShQTfv2FoISZJAZ4dlUcekG8-CSkgJh0i0q_iJn",' + b'"i":"","rp":"","p":"","dt":"","r":"","q":{},"a":[],"e":{}}') assert serder.verify() # because pre is empty assert serder.ilk == kering.Ilks.exn diff --git a/tests/peer/test_exchanging.py b/tests/peer/test_exchanging.py index 378f08acb..3c555bb12 100644 --- a/tests/peer/test_exchanging.py +++ b/tests/peer/test_exchanging.py @@ -98,26 +98,24 @@ def test_hab_exchange(mockHelpingNowUTC): data = dict(m="Let's create a registry") msg = hab.exchange(route="/multisig/registry/incept", recipient="", payload=data, embeds=embeds) - assert msg == (b'{"v":"KERI10JSON000398_","t":"exn","d":"ECcmfGnlqnc5-1_oXNpbfowv' - b'RsEa-V8tfeKmQDRJJ50i","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2Q' - b'V8dDjI3","p":"","dt":"2021-01-01T00:00:00.000000+00:00","r":"/mu' - b'ltisig/registry/incept","q":{},"a":{"i":"","m":"Let\'s create a r' - b'egistry"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp","d":"EI6' - b'hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","i":"EI6hBlgkWoJgkZyf' - b'LW35_UyM4nIK44OgsSwFR_WOfvVB","ii":"EIaGMMWJFPmtXznY1IIiKDIrg-vI' - b'yge6mBl2QV8dDjI3","s":"0","c":[],"bt":"0","b":[],"n":"AH3-1EZWXU' - b'9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10JSON00013' - b'8_","t":"ixn","d":"EFuFnevyDFfpWG6il-6Qcv0ne0ZIItLwanCwI-SU8A9j"' - b',"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"1","p":' - b'"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","a":[{"i":"EI6hBl' - b'gkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","s":0,"d":"EI6hBlgkWoJgk' - b'ZyfLW35_UyM4nIK44OgsSwFR_WOfvVB"}]},"d":"EL5Nkm6T7HG_0GW6uwqYSZw' - b'lH23khtXvsVE-dq8eO_eE"}}-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2' - b'QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6' - b'mBl2QV8dDjI3-AABAACahD6g7IwjUyQRyGUPGLvlr5-DsvLxeJtCUVIIECYfAQ_q' - b'p3Z2pe__HRqIl-NrUv85oQrZBm0kpKn8LBQtQfkO-LAa5AACAA-e-ixn-AABAADp' - b'rTWp4llIzVzBM7VVsDOgXVJdoiVXutsWJEbDJ2pMdjXjNi1xKALBSZ1ZgRoUsD--' - b'LgUQkXIdjLoQ19XPvJMJ') + assert msg == (b'{"v":"KERI10JSON0003a0_","t":"exn","d":"ELkHqph-Tj4LGHYfFfoVmJJo09S2gp6ci8rK96upIAKE",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"","p":"",' + b'"dt":"2021-01-01T00:00:00.000000+00:00","r":"/multisig/registry/incept","q":{},"a":{"i":"",' + b'"m":"Let\'s create a registry"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp",' + b'"d":"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB",' + b'"i":"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB",' + b'"ii":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"0","c":[],"bt":"0","b":[],' + b'"n":"AH3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10JSON000138_",' + b'"t":"ixn","d":"EFuFnevyDFfpWG6il-6Qcv0ne0ZIItLwanCwI-SU8A9j",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"1",' + b'"p":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3",' + b'"a":[{"i":"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","s":0,' + b'"d":"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB"}]},' + b'"d":"EL5Nkm6T7HG_0GW6uwqYSZwlH23khtXvsVE-dq8eO_eE"}}-FABEIaGMMWJFPmtXznY1IIiKDIrg' + b'-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3' + b'-AABAAB-teJc_7zot5TAZT6lQi2-GlBzMHXICvt3tIYoPo2gYXF7PpWDozo3y3wVW9mgHln-1DvQlqn9Aip1YnBgKUQB' + b'-LAa5AACAA-e-ixn-AABAADprTWp4llIzVzBM7VVsDOgXVJdoiVXutsWJEbDJ2pMdjXjNi1xKALBSZ1ZgRoUsD' + b'--LgUQkXIdjLoQ19XPvJMJ') exn = serdering.SerderKERI(raw=msg) @@ -140,27 +138,25 @@ def test_hab_exchange(mockHelpingNowUTC): data = dict(m="Lets create this registry instead") msg = hab2.exchange(route="/multisig/registry/incept", payload=data, recipient="", dig=exn.said, embeds=embeds) - assert msg == (b'{"v":"KERI10JSON0003ce_","t":"exn","d":"EEMxkjO9HzZoekfzmjrkE19y' - b'pU259apUWuY7alFu_GmE","i":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVli' - b'I61Bcc2","p":"ECcmfGnlqnc5-1_oXNpbfowvRsEa-V8tfeKmQDRJJ50i","dt"' - b':"2021-01-01T00:00:00.000000+00:00","r":"/multisig/registry/ince' - b'pt","q":{},"a":{"i":"","m":"Lets create this registry instead"},' - b'"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp","d":"EB5mts6qrWOZr' - b'xjma6lSTjAdPZ0NSHM1HC3IndbS_giB","i":"EB5mts6qrWOZrxjma6lSTjAdPZ' - b'0NSHM1HC3IndbS_giB","ii":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI' - b'61Bcc2","s":"0","c":[],"bt":"0","b":[],"n":"AH3-1EZWXU9I0fv3Iz_9' - b'ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10JSON000138_","t":"i' - b'xn","d":"EOek9JVKNeuW-5UNeHYCTDe70_GtvRwP672oWMNBJpA5","i":"EIRE' - b'QlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"1","p":"EIREQlatU' - b'JODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","a":[{"i":"EB5mts6qrWOZrxjm' - b'a6lSTjAdPZ0NSHM1HC3IndbS_giB","s":0,"d":"EB5mts6qrWOZrxjma6lSTjA' - b'dPZ0NSHM1HC3IndbS_giB"}]},"d":"EM3gLTzQ9GmKd50Rlm_kiIkeYkxb004eo' - b'OsWahz70TqJ"}}-FABEIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc20A' - b'AAAAAAAAAAAAAAAAAAAAAAEIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bc' - b'c2-AABAAAxpwQLr9-D7hOZYHvvDB_ffo5sRgBf0NufowF0g_YMI1wdnttlYA2o_d' - b'wtK_WNbfh_iAytFw9nHZziCED13AwH-LAa5AACAA-e-ixn-AABAACaoxfQp5L_Gd' - b'0nKqJXMbLTXzkrJJDd8RFxWdTSesAMydUzmJQlGt0T9h8L7SwIrq8yBinj990PLJ' - b'Hl7sXmq04I') + assert msg == (b'{"v":"KERI10JSON0003d6_","t":"exn","d":"EPO_XC9nwSixqSoOvsHymFr-l3udclHBdOh4OUEqZ33P",' + b'"i":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","rp":"",' + b'"p":"ELkHqph-Tj4LGHYfFfoVmJJo09S2gp6ci8rK96upIAKE","dt":"2021-01-01T00:00:00.000000+00:00",' + b'"r":"/multisig/registry/incept","q":{},"a":{"i":"","m":"Lets create this registry instead"},' + b'"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp",' + b'"d":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB",' + b'"i":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB",' + b'"ii":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"0","c":[],"bt":"0","b":[],' + b'"n":"AH3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10JSON000138_",' + b'"t":"ixn","d":"EOek9JVKNeuW-5UNeHYCTDe70_GtvRwP672oWMNBJpA5",' + b'"i":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"1",' + b'"p":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2",' + b'"a":[{"i":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","s":0,' + b'"d":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB"}]},' + b'"d":"EM3gLTzQ9GmKd50Rlm_kiIkeYkxb004eoOsWahz70TqJ' + b'"}}-FABEIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc20AAAAAAAAAAAAAAAAAAAAAAAEIREQlatUJODbKogZ' + b'fa3IqXZ90XdZA0qJMVliI61Bcc2-AABAADY5nUsBgL23ulcrTgkV09hSzktNHZSlEH1zmVpEggrGgQUq0tLQeOXztUFD' + b'xNQ4Kq2ddIYDVz6d_y0kkU3__YJ-LAa5AACAA-e-ixn-AABAACaoxfQp5L_Gd0nKqJXMbLTXzkrJJDd8RFxWdTSesAMy' + b'dUzmJQlGt0T9h8L7SwIrq8yBinj990PLJHl7sXmq04I') # Test exn from non-transferable AID hab = hby.makeHab(name="test1", transferable=False) @@ -171,18 +167,16 @@ def test_hab_exchange(mockHelpingNowUTC): ) msg = hab.exchange(route="/multisig/registry/incept", payload=data, embeds=embeds, recipient="") - assert msg == (b'{"v":"KERI10JSON000263_","t":"exn","d":"ENRFAVDU_ZbcVpx6l6lrC5Mu' - b'UqHXfT3N9VjUkvU4t29S","i":"BJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6-tFV' - b'lCeiZPG","p":"","dt":"2021-01-01T00:00:00.000000+00:00","r":"/mu' - b'ltisig/registry/incept","q":{},"a":{"i":"","m":"Lets create this' - b' registry instead"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp' - b'","d":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","i":"EB5mts' - b'6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","ii":"EIREQlatUJODbKogZf' - b'a3IqXZ90XdZA0qJMVliI61Bcc2","s":"0","c":[],"bt":"0","b":[],"n":"' - b'AH3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"d":"ENC6w8wUj-Gp' - b'_RpAJN5q4Lf00IHstzNLUvkh3ZvgHGP_"}}-CABBJZ_LF61JTCCSCIw2Q4ozE2Ms' - b'bRC4m-N6-tFVlCeiZPG0BCxLApuSnk1MF9IUq1RJNjVmr6s-fLwvP6aAPa0ag34t' - b'4G7EKKk-UFwy74-0StSlHcS8KBkN5ZbtuHvV9tXRqUJ-LAl5AACAA-e-vcp-CABB' - b'JZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6-tFVlCeiZPG0BDjOC4j0Co6P0giMylR4' - b'7149eJ8Yf_hO-32_TpY77KMVCWCf0U8GuZPIN76R2zsyT_eARvS_zQsX1ebjl3PM' - b'P0D') + assert msg == (b'{"v":"KERI10JSON00026b_","t":"exn","d":"EMBm0p7fCIqJrP4Z-PBI-yEvXin_-eY1dU4XTCM9ykRC",' + b'"i":"BJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6-tFVlCeiZPG","rp":"","p":"",' + b'"dt":"2021-01-01T00:00:00.000000+00:00","r":"/multisig/registry/incept","q":{},"a":{"i":"",' + b'"m":"Lets create this registry instead"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp",' + b'"d":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB",' + b'"i":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB",' + b'"ii":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"0","c":[],"bt":"0","b":[],' + b'"n":"AH3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},' + b'"d":"ENC6w8wUj-Gp_RpAJN5q4Lf00IHstzNLUvkh3ZvgHGP_"}}-CABBJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6' + b'-tFVlCeiZPG0BB-sQs0WS9wsyuT4hXQD7rbczSfpnQz21wZGYucRkE0ynKy5draELEKBsckeD0Im1i' + b'-kIfMEdbY08YqVfSrEoAA-LAl5AACAA-e-vcp-CABBJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6' + b'-tFVlCeiZPG0BDjOC4j0Co6P0giMylR47149eJ8Yf_hO' + b'-32_TpY77KMVCWCf0U8GuZPIN76R2zsyT_eARvS_zQsX1ebjl3PMP0D') diff --git a/tests/vc/test_protocoling.py b/tests/vc/test_protocoling.py index befb8dcbb..cff1ae6d0 100644 --- a/tests/vc/test_protocoling.py +++ b/tests/vc/test_protocoling.py @@ -115,26 +115,29 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN apply0, apply0atc = protocoling.ipexApplyExn(sidHab, message="Please give me a credential", schema=schema, recp=redPre, attrs={}) - assert apply0.raw == (b'{"v":"KERI10JSON00016d_","t":"exn","d":"EI1MnUrT0aUprMN97FabgJdxVQtoCPqamVUp' - b'3iFgnDBE","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"","dt":"20' - b'21-06-27T21:26:21.233257+00:00","r":"/ipex/apply","q":{},"a":{"m":"Please gi' - b've me a credential","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{' - b'},"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{}}') + assert apply0.raw == (b'{"v":"KERI10JSON000175_","t":"exn","d":"EK9Q7n1y-Rlf-A7-T0uWSKuOlHZHBy_4zVaNp60GxXEr",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/apply","q":{},"a":{"m":"Please ' + b'give me a credential","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{},' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{}}') # No requirements for apply, except that its first, no `p` assert ipexhan.verify(serder=apply0) is True offer0, offer0atc = protocoling.ipexOfferExn(sidHab, "How about this", acdc=creder.raw, apply=apply0) - assert offer0.raw == (b'{"v":"KERI10JSON0002f0_","t":"exn","d":"EO_wiH5ZEikfLQb8rKBjPATnjiSOHGBvvN3m' - b'F0LDvaIC","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EI1MnUrT0a' - b'UprMN97FabgJdxVQtoCPqamVUp3iFgnDBE","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/offer","q":{},"a":{"m":"How about this"},"e":{"acdc":{"v":"ACDC10' - b'JSON000197_","d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","i":"EIaGMMW' - b'JFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGs' - b'jaXFOaO_kCfS4","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"' - b'EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx","dt":"2021-06-27T21:26:21.2332' - b'57+00:00","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OP' - b'PU84GM83MG36"}},"d":"EOVRKHUAEjvfyWzQ8IL4icBiaVuy_CSTse_W_AssaAeE"}}') + assert offer0.raw == (b'{"v":"KERI10JSON0002f8_","t":"exn","d":"ED-uXbt7hRH3cmQY9vtwmcPOGvdmPEq_bnQ4sgQK9KhB",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"EK9Q7n1y-Rlf-A7-T0uWSKuOlHZHBy_4zVaNp60GxXEr",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/offer","q":{},"a":{"m":"How about ' + b'this"},"e":{"acdc":{"v":"ACDC10JSON000197_",' + b'"d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC",' + b'"a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx",' + b'"dt":"2021-06-27T21:26:21.233257+00:00",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},' + b'"d":"EOVRKHUAEjvfyWzQ8IL4icBiaVuy_CSTse_W_AssaAeE"}}') # This should fail because it is not first and the apply isn't persisted yet assert ipexhan.verify(serder=offer0) is False @@ -161,26 +164,29 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN # Let's see if we can spurn a message we previously accepted. spurn0, spurn0atc = protocoling.ipexSpurnExn(sidHab, "I reject you", spurned=apply0) - assert spurn0.raw == (b'{"v":"KERI10JSON00011d_","t":"exn","d":"EKvtmxPkOklgRNgWxLj-1ZW4Zb0MwZIUloWx' - b'A_dam95r","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EI1MnUrT0a' - b'UprMN97FabgJdxVQtoCPqamVUp3iFgnDBE","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/spurn","q":{},"a":{"m":"I reject you"},"e":{}}') + assert spurn0.raw == (b'{"v":"KERI10JSON000125_","t":"exn","d":"EP9mGfCLrVs-A2KiSwruQ8bdQVlPIiIFZ2t4f6Dj4gnc",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"EK9Q7n1y-Rlf-A7-T0uWSKuOlHZHBy_4zVaNp60GxXEr",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/spurn","q":{},"a":{"m":"I reject ' + b'you"},"e":{}}') # This will fail, we've already responded with an offer assert ipexhan.verify(spurn0) is False # Now lets try an offer without a pointer back to a reply offer1, offer1atc = protocoling.ipexOfferExn(sidHab, "Here a credential offer", acdc=creder.raw) - assert offer1.raw == (b'{"v":"KERI10JSON0002cd_","t":"exn","d":"EMEmoi4k9gxWu4uZyYuEK3MvFPn-5B0LHnNx' - b'uQ4vRqRA","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"","dt":"20' - b'21-06-27T21:26:21.233257+00:00","r":"/ipex/offer","q":{},"a":{"m":"Here a cr' - b'edential offer"},"e":{"acdc":{"v":"ACDC10JSON000197_","d":"EDkftEwWBpohjTpem' - b'h_6xkaGNuoDsRU3qwvHdlvgfOyG","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDj' - b'I3","ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4","s":"EMQWEcCnVRk1hat' - b'TNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwch' - b'O9yylr3xx","dt":"2021-06-27T21:26:21.233257+00:00","i":"EIaGMMWJFPmtXznY1IIi' - b'KDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},"d":"EOVRKHUAEjvfyW' - b'zQ8IL4icBiaVuy_CSTse_W_AssaAeE"}}') + assert offer1.raw == (b'{"v":"KERI10JSON0002d5_","t":"exn","d":"EJC9_GH0TeYJ3_cyutkS1gZfcgaGUQnk3v7F_gwJShVM",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/offer","q":{},"a":{"m":"Here a ' + b'credential offer"},"e":{"acdc":{"v":"ACDC10JSON000197_",' + b'"d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC",' + b'"a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx",' + b'"dt":"2021-06-27T21:26:21.233257+00:00",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},' + b'"d":"EOVRKHUAEjvfyWzQ8IL4icBiaVuy_CSTse_W_AssaAeE"}}') # Will work because it is starting a new conversation assert ipexhan.verify(serder=offer1) is True @@ -192,10 +198,11 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN assert serder.ked == offer1.ked agree, argeeAtc = protocoling.ipexAgreeExn(sidHab, "I'll accept that offer", offer=offer0) - assert agree.raw == (b'{"v":"KERI10JSON000127_","t":"exn","d":"EGpJ9S0TqIVHkRmDsbgP59NC8ZLCaSUirslB' - b'KDeYKOR7","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EO_wiH5ZEi' - b'kfLQb8rKBjPATnjiSOHGBvvN3mF0LDvaIC","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/agree","q":{},"a":{"m":"I\'ll accept that offer"},"e":{}}') + assert agree.raw == (b'{"v":"KERI10JSON00012f_","t":"exn","d":"ELLFpKUv8qt6UKaNFj2_s-3Hs1vFeRgWdq_LIQm2HEER",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"ED-uXbt7hRH3cmQY9vtwmcPOGvdmPEq_bnQ4sgQK9KhB",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/agree","q":{},"a":{"m":"I\'ll ' + b'accept that offer"},"e":{}}') # Can not create an agree without an offer, so this will pass since it has an offer that has no response assert ipexhan.verify(serder=agree) is True @@ -210,24 +217,28 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN anc = sidHab.makeOwnEvent(sn=2) grant0, grant0atc = protocoling.ipexGrantExn(sidHab, message="Here's a credential", recp=sidHab.pre, acdc=msg, iss=iss.raw, anc=anc) - assert grant0.raw == (b'{"v":"KERI10JSON000531_","t":"exn","d":"EJxM3em5fSpAIQsyXYovrr0UjblWLtmbTnFp' - b'xAUqnwG-","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"","dt":"20' - b'21-06-27T21:26:21.233257+00:00","r":"/ipex/grant","q":{},"a":{"m":"Here\'' - b's a credential","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{"ac' - b'dc":{"v":"ACDC10JSON000197_","d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfO' - b'yG","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","ri":"EO0_SyqPS1-EVYS' - b'ITakYpUHaUZZpZGsjaXFOaO_kCfS4","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gk' - b'k1kC","a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx","dt":"2021-06-' - b'27T21:26:21.233257+00:00","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"' - b',"LEI":"254900OPPU84GM83MG36"}},"iss":{"v":"KERI10JSON0000ed_","t":"iss","d"' - b':"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3","i":"EDkftEwWBpohjTpemh_6xka' - b'GNuoDsRU3qwvHdlvgfOyG","s":"0","ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_' - b'kCfS4","dt":"2021-06-27T21:26:21.233257+00:00"},"anc":{"v":"KERI10JSON00013a' - b'_","t":"ixn","d":"EOjAxp-AMLzicGz2h-DxvMK9kicajpZEwdN8-8k54hvz","i":"EIaGMMW' - b'JFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"2","p":"EGKglEgIpdHuhuwl-IiSDG9x' - b'094gMrRxVaXGgXvCzCYM","a":[{"i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOy' - b'G","s":"0","d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3"}]},"d":"EI5mZX' - b'Z84Su4DrEUOxtl-NaUURQtTJeAn12xf146beg3"}}') + assert grant0.raw == (b'{"v":"KERI10JSON000539_","t":"exn","d":"EBXaaGfKREvo3UbvNEtgTiZySHe71tTU4-ZmcFETVdn8",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/grant","q":{},"a":{"m":"Here\'s a ' + b'credential","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{"acdc":{' + b'"v":"ACDC10JSON000197_","d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC",' + b'"a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx",' + b'"dt":"2021-06-27T21:26:21.233257+00:00",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},' + b'"iss":{"v":"KERI10JSON0000ed_","t":"iss",' + b'"d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3",' + b'"i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"dt":"2021-06-27T21:26:21.233257+00:00"},"anc":{"v":"KERI10JSON00013a_","t":"ixn",' + b'"d":"EOjAxp-AMLzicGz2h-DxvMK9kicajpZEwdN8-8k54hvz",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"2",' + b'"p":"EGKglEgIpdHuhuwl-IiSDG9x094gMrRxVaXGgXvCzCYM",' + b'"a":[{"i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0",' + b'"d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3"}]},' + b'"d":"EI5mZXZ84Su4DrEUOxtl-NaUURQtTJeAn12xf146beg3"}}') assert ipexhan.verify(serder=grant0) is True @@ -240,10 +251,11 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN # Let's see if we can spurn a message we previously accepted. spurn1, spurn1atc = protocoling.ipexSpurnExn(sidHab, "I reject you", spurned=grant0) - assert spurn1.raw == (b'{"v":"KERI10JSON00011d_","t":"exn","d":"EEs0bIGplWsjSOw5BMhAdFmgv-jm3-4nPgcK' - b'-LDv8tdB","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EJxM3em5fS' - b'pAIQsyXYovrr0UjblWLtmbTnFpxAUqnwG-","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/spurn","q":{},"a":{"m":"I reject you"},"e":{}}') + assert spurn1.raw == (b'{"v":"KERI10JSON000125_","t":"exn","d":"EIoMDwEvyR4j43W5Hh9CyJ4ttwNHlrmABwyUvKHhF9mp",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"EBXaaGfKREvo3UbvNEtgTiZySHe71tTU4-ZmcFETVdn8",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/spurn","q":{},"a":{"m":"I reject ' + b'you"},"e":{}}') smsg = bytearray(spurn1.raw) smsg.extend(spurn1atc) parsing.Parser().parse(ims=smsg, exc=sidExc) @@ -253,25 +265,29 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN # Now we'll run a grant pointing back to the agree all the way to the database grant1, grant1atc = protocoling.ipexGrantExn(sidHab, message="Here's a credential", acdc=msg, iss=iss.raw, recp=sidHab.pre, anc=anc, agree=agree) - assert grant1.raw == (b'{"v":"KERI10JSON00055d_","t":"exn","d":"EIqh-L9GnnVSdNLeqwmx-vpE9V1DvOQAlVWf' - b'wENpm8sW","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EGpJ9S0TqI' - b'VHkRmDsbgP59NC8ZLCaSUirslBKDeYKOR7","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/grant","q":{},"a":{"m":"Here\'s a credential","i":"EIaGMMWJFPm' - b'tXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{"acdc":{"v":"ACDC10JSON000197_","d"' - b':"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","i":"EIaGMMWJFPmtXznY1IIiKDI' - b'rg-vIyge6mBl2QV8dDjI3","ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4","' - b's":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EF2__B6DiLQHpdJZ' - b'_C0bddxy2o6nXIHEwchO9yylr3xx","dt":"2021-06-27T21:26:21.233257+00:00","i":"E' - b'IaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},' - b'"iss":{"v":"KERI10JSON0000ed_","t":"iss","d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYh' - b'JL9afqdCIZjMy3","i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0","' - b'ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4","dt":"2021-06-27T21:26:21' - b'.233257+00:00"},"anc":{"v":"KERI10JSON00013a_","t":"ixn","d":"EOjAxp-AMLzicG' - b'z2h-DxvMK9kicajpZEwdN8-8k54hvz","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8' - b'dDjI3","s":"2","p":"EGKglEgIpdHuhuwl-IiSDG9x094gMrRxVaXGgXvCzCYM","a":[{"i":' - b'"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0","d":"EK2WxcpF3oL1yqS3' - b'Z8i08WDYkHDcYhJL9afqdCIZjMy3"}]},"d":"EI5mZXZ84Su4DrEUOxtl-NaUURQtTJeAn12xf1' - b'46beg3"}}') + assert grant1.raw == (b'{"v":"KERI10JSON000565_","t":"exn","d":"ENy1ktZHowD73mn0vJL-xpTzCDpa4RuISZldAZImiKD_",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"ELLFpKUv8qt6UKaNFj2_s-3Hs1vFeRgWdq_LIQm2HEER",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/grant","q":{},"a":{"m":"Here\'s a ' + b'credential","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3"},"e":{"acdc":{' + b'"v":"ACDC10JSON000197_","d":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC",' + b'"a":{"d":"EF2__B6DiLQHpdJZ_C0bddxy2o6nXIHEwchO9yylr3xx",' + b'"dt":"2021-06-27T21:26:21.233257+00:00",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","LEI":"254900OPPU84GM83MG36"}},' + b'"iss":{"v":"KERI10JSON0000ed_","t":"iss",' + b'"d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3",' + b'"i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0",' + b'"ri":"EO0_SyqPS1-EVYSITakYpUHaUZZpZGsjaXFOaO_kCfS4",' + b'"dt":"2021-06-27T21:26:21.233257+00:00"},"anc":{"v":"KERI10JSON00013a_","t":"ixn",' + b'"d":"EOjAxp-AMLzicGz2h-DxvMK9kicajpZEwdN8-8k54hvz",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":"2",' + b'"p":"EGKglEgIpdHuhuwl-IiSDG9x094gMrRxVaXGgXvCzCYM",' + b'"a":[{"i":"EDkftEwWBpohjTpemh_6xkaGNuoDsRU3qwvHdlvgfOyG","s":"0",' + b'"d":"EK2WxcpF3oL1yqS3Z8i08WDYkHDcYhJL9afqdCIZjMy3"}]},' + b'"d":"EI5mZXZ84Su4DrEUOxtl-NaUURQtTJeAn12xf146beg3"}}') assert ipexhan.verify(serder=grant1) is True gmsg = bytearray(grant1.raw) @@ -282,10 +298,11 @@ def test_ipex(seeder, mockCoringRandomNonce, mockHelpingNowIso8601, mockHelpingN # And now the last... admit the granted credential to complete the full flow admit0, admit0atc = protocoling.ipexAdmitExn(sidHab, "Thanks for the credential", grant=grant1) - assert admit0.raw == (b'{"v":"KERI10JSON00012a_","t":"exn","d":"ELNz82kqV94vlbT7lJulVFWtf6_jhGRgH556' - b'Z-xYRaGY","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","p":"EIqh-L9Gnn' - b'VSdNLeqwmx-vpE9V1DvOQAlVWfwENpm8sW","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/admit","q":{},"a":{"m":"Thanks for the credential"},"e":{}}') + assert admit0.raw == (b'{"v":"KERI10JSON000132_","t":"exn","d":"EAnQEaL-jSGK22VSbPN7WAUWVcxJ9LV8S5fORVAqVQzN",' + b'"i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","rp":"",' + b'"p":"ENy1ktZHowD73mn0vJL-xpTzCDpa4RuISZldAZImiKD_",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/admit","q":{},"a":{"m":"Thanks for ' + b'the credential"},"e":{}}') assert ipexhan.verify(serder=admit0) is True amsg = bytearray(admit0.raw) From 1c9bc52e203cbff2cfc1bc8d4df115db11e6e8b0 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Sat, 14 Dec 2024 09:16:06 -0500 Subject: [PATCH 44/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index a1b599bad..76f20b95f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.26 +VERSION=1.1.27 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 414caf21b..52fae4386 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.26` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.27` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 62472a123..3a70c5fec 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.26', # also change in src/keri/__init__.py + version='1.1.27', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index acf6b830c..52782836c 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.26' # also change in setup.py +__version__ = '1.1.27' # also change in setup.py From b8479d3cf9f42b4ba56db60bca71fb7ce2dadde9 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Sun, 15 Dec 2024 07:58:20 -0700 Subject: [PATCH 45/61] refactor: logging should use keri.help, not hio.help (#907) --- src/keri/app/apping.py | 2 -- src/keri/app/cli/commands/challenge/generate.py | 2 +- src/keri/app/cli/commands/challenge/verify.py | 2 +- src/keri/app/cli/commands/contacts/list.py | 2 +- src/keri/app/cli/commands/did/generate.py | 2 +- src/keri/app/cli/commands/ends/add.py | 2 +- src/keri/app/cli/commands/ends/export.py | 4 ++-- src/keri/app/cli/commands/ends/list.py | 4 +--- src/keri/app/cli/commands/escrow/clear.py | 2 +- src/keri/app/cli/commands/escrow/list.py | 2 +- src/keri/app/cli/commands/export.py | 4 ++-- src/keri/app/cli/commands/incept.py | 2 +- src/keri/app/cli/commands/init.py | 2 +- src/keri/app/cli/commands/ipex/list.py | 2 +- src/keri/app/cli/commands/kevers.py | 4 ++-- src/keri/app/cli/commands/list.py | 3 +-- src/keri/app/cli/commands/local/watch.py | 3 +-- src/keri/app/cli/commands/mailbox/debug.py | 8 +++----- src/keri/app/cli/commands/mailbox/update.py | 2 +- src/keri/app/cli/commands/migrate/show.py | 2 +- src/keri/app/cli/commands/multisig/continue.py | 2 +- src/keri/app/cli/commands/multisig/interact.py | 2 +- src/keri/app/cli/commands/multisig/notice.py | 2 +- src/keri/app/cli/commands/multisig/rotate.py | 2 +- src/keri/app/cli/commands/multisig/update.py | 2 +- src/keri/app/cli/commands/oobi/clean.py | 2 +- src/keri/app/cli/commands/oobi/generate.py | 2 +- src/keri/app/cli/commands/oobi/resolve.py | 3 +-- src/keri/app/cli/commands/passcode/remove.py | 2 +- src/keri/app/cli/commands/passcode/set.py | 2 +- src/keri/app/cli/commands/query.py | 2 +- src/keri/app/cli/commands/rename.py | 2 +- src/keri/app/cli/commands/rollback.py | 2 +- src/keri/app/cli/commands/saidify.py | 2 +- src/keri/app/cli/commands/ssh/export.py | 2 +- src/keri/app/cli/commands/status.py | 4 ++-- src/keri/app/cli/commands/vc/create.py | 2 +- src/keri/app/cli/commands/vc/export.py | 2 +- src/keri/app/cli/commands/vc/list.py | 2 +- src/keri/app/cli/commands/vc/registry/incept.py | 4 ++-- src/keri/app/cli/commands/vc/registry/list.py | 2 +- src/keri/app/cli/commands/vc/registry/status.py | 4 ++-- src/keri/app/cli/commands/witness/submit.py | 2 +- src/keri/app/cli/kli.py | 2 +- src/keri/app/delegating.py | 4 ++-- src/keri/app/forwarding.py | 5 +++-- src/keri/demo/demo_kev.py | 5 ++--- src/keri/vdr/viring.py | 5 +---- tests/help/test_ogling.py | 2 +- 49 files changed, 60 insertions(+), 72 deletions(-) diff --git a/src/keri/app/apping.py b/src/keri/app/apping.py index 7478aa1d2..4464633db 100644 --- a/src/keri/app/apping.py +++ b/src/keri/app/apping.py @@ -4,8 +4,6 @@ keri.app.apping module """ -import cmd - from hio.base import doing from hio.core.serial import serialing diff --git a/src/keri/app/cli/commands/challenge/generate.py b/src/keri/app/cli/commands/challenge/generate.py index e26e6f10e..169ea93c7 100644 --- a/src/keri/app/cli/commands/challenge/generate.py +++ b/src/keri/app/cli/commands/challenge/generate.py @@ -6,7 +6,7 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from mnemonic import mnemonic diff --git a/src/keri/app/cli/commands/challenge/verify.py b/src/keri/app/cli/commands/challenge/verify.py index db27501ee..f82fbf1c4 100644 --- a/src/keri/app/cli/commands/challenge/verify.py +++ b/src/keri/app/cli/commands/challenge/verify.py @@ -8,7 +8,7 @@ import datetime import sys -from hio import help +from keri import help from hio.base import doing from keri.app import indirecting, challenging, connecting, signaling diff --git a/src/keri/app/cli/commands/contacts/list.py b/src/keri/app/cli/commands/contacts/list.py index 1ba574483..b93c1e248 100644 --- a/src/keri/app/cli/commands/contacts/list.py +++ b/src/keri/app/cli/commands/contacts/list.py @@ -7,7 +7,7 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/did/generate.py b/src/keri/app/cli/commands/did/generate.py index 9e0cb28d1..5398ca35b 100644 --- a/src/keri/app/cli/commands/did/generate.py +++ b/src/keri/app/cli/commands/did/generate.py @@ -9,7 +9,7 @@ from urllib.parse import urlparse import sys -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/ends/add.py b/src/keri/app/cli/commands/ends/add.py index e672abfda..76cb623ec 100644 --- a/src/keri/app/cli/commands/ends/add.py +++ b/src/keri/app/cli/commands/ends/add.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/ends/export.py b/src/keri/app/cli/commands/ends/export.py index e1d54a2f3..e340272d8 100644 --- a/src/keri/app/cli/commands/ends/export.py +++ b/src/keri/app/cli/commands/ends/export.py @@ -6,12 +6,12 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri import kering from keri.app.cli.common import existing -from keri.core import coring, eventing +from keri.core import eventing logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/ends/list.py b/src/keri/app/cli/commands/ends/list.py index 533e39d95..1f0035a3b 100644 --- a/src/keri/app/cli/commands/ends/list.py +++ b/src/keri/app/cli/commands/ends/list.py @@ -7,13 +7,11 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from keri import kering -from keri.app import indirecting, habbing, forwarding, grouping from keri.app.cli.common import existing -from keri.core import eventing, parsing, coring logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/escrow/clear.py b/src/keri/app/cli/commands/escrow/clear.py index e715a4427..e6e98924e 100644 --- a/src/keri/app/cli/commands/escrow/clear.py +++ b/src/keri/app/cli/commands/escrow/clear.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing from keri.vdr import viring diff --git a/src/keri/app/cli/commands/escrow/list.py b/src/keri/app/cli/commands/escrow/list.py index 4e647c3d9..dd4aa8c5c 100644 --- a/src/keri/app/cli/commands/escrow/list.py +++ b/src/keri/app/cli/commands/escrow/list.py @@ -7,7 +7,7 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from keri.core import eventing diff --git a/src/keri/app/cli/commands/export.py b/src/keri/app/cli/commands/export.py index 7fe7dfff9..a2ef4d2b7 100644 --- a/src/keri/app/cli/commands/export.py +++ b/src/keri/app/cli/commands/export.py @@ -7,11 +7,11 @@ import argparse import sys -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing -from keri.core import coring, serdering +from keri.core import serdering logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/incept.py b/src/keri/app/cli/commands/incept.py index fbc59560a..87977ebd5 100644 --- a/src/keri/app/cli/commands/incept.py +++ b/src/keri/app/cli/commands/incept.py @@ -6,7 +6,7 @@ import argparse from dataclasses import dataclass -from hio import help +from keri import help from hio.base import doing from keri.app import habbing, agenting, indirecting, configing, delegating, forwarding diff --git a/src/keri/app/cli/commands/init.py b/src/keri/app/cli/commands/init.py index aa8479ec6..04a1ae45c 100644 --- a/src/keri/app/cli/commands/init.py +++ b/src/keri/app/cli/commands/init.py @@ -6,7 +6,7 @@ import argparse import getpass -from hio import help +from keri import help from hio.base import doing import keri.app.oobiing diff --git a/src/keri/app/cli/commands/ipex/list.py b/src/keri/app/cli/commands/ipex/list.py index 4f59d9816..89449d87f 100644 --- a/src/keri/app/cli/commands/ipex/list.py +++ b/src/keri/app/cli/commands/ipex/list.py @@ -10,7 +10,7 @@ import os import sys -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/kevers.py b/src/keri/app/cli/commands/kevers.py index 3eaf42aca..3cc6eb905 100644 --- a/src/keri/app/cli/commands/kevers.py +++ b/src/keri/app/cli/commands/kevers.py @@ -8,12 +8,12 @@ import datetime import sys -from hio import help +from keri import help from hio.base import doing from keri.app import indirecting from keri.app.cli.common import displaying, existing -from keri.core import coring, serdering +from keri.core import serdering from keri.help import helping logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/list.py b/src/keri/app/cli/commands/list.py index d02f162ca..4d36d622f 100644 --- a/src/keri/app/cli/commands/list.py +++ b/src/keri/app/cli/commands/list.py @@ -6,11 +6,10 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing -from keri.kering import ConfigurationError logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/local/watch.py b/src/keri/app/cli/commands/local/watch.py index 6529f80e9..3558a0f44 100644 --- a/src/keri/app/cli/commands/local/watch.py +++ b/src/keri/app/cli/commands/local/watch.py @@ -9,12 +9,11 @@ import time from collections import namedtuple -from hio import help +from keri import help from hio.base import doing from keri.app import agenting, indirecting, habbing, forwarding from keri.app.cli.common import existing, terming from keri.app.habbing import GroupHab -from keri.core import coring logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/mailbox/debug.py b/src/keri/app/cli/commands/mailbox/debug.py index de7f425ba..6cf5fe964 100644 --- a/src/keri/app/cli/commands/mailbox/debug.py +++ b/src/keri/app/cli/commands/mailbox/debug.py @@ -6,15 +6,13 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri import kering -from keri.app import agenting, indirecting, habbing, httping -from keri.app.cli.common import displaying, existing +from keri.app import agenting, habbing, httping +from keri.app.cli.common import existing from keri.app.habbing import GroupHab -from keri.core import coring -from keri.kering import ConfigurationError logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/mailbox/update.py b/src/keri/app/cli/commands/mailbox/update.py index 0c191bb94..8ac16cd93 100644 --- a/src/keri/app/cli/commands/mailbox/update.py +++ b/src/keri/app/cli/commands/mailbox/update.py @@ -5,7 +5,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/migrate/show.py b/src/keri/app/cli/commands/migrate/show.py index 1ff745815..6bf3392c5 100644 --- a/src/keri/app/cli/commands/migrate/show.py +++ b/src/keri/app/cli/commands/migrate/show.py @@ -5,7 +5,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/multisig/continue.py b/src/keri/app/cli/commands/multisig/continue.py index 2a2508f97..f419a7418 100644 --- a/src/keri/app/cli/commands/multisig/continue.py +++ b/src/keri/app/cli/commands/multisig/continue.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app import indirecting, grouping, agenting diff --git a/src/keri/app/cli/commands/multisig/interact.py b/src/keri/app/cli/commands/multisig/interact.py index 77b98ff73..b5abef1e8 100644 --- a/src/keri/app/cli/commands/multisig/interact.py +++ b/src/keri/app/cli/commands/multisig/interact.py @@ -7,7 +7,7 @@ import argparse from ordered_set import OrderedSet as oset -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/multisig/notice.py b/src/keri/app/cli/commands/multisig/notice.py index 70902b2fb..fe4ca2769 100644 --- a/src/keri/app/cli/commands/multisig/notice.py +++ b/src/keri/app/cli/commands/multisig/notice.py @@ -6,7 +6,7 @@ import argparse from ordered_set import OrderedSet as oset -from hio import help +from keri import help from hio.base import doing from keri.app import habbing, forwarding, grouping diff --git a/src/keri/app/cli/commands/multisig/rotate.py b/src/keri/app/cli/commands/multisig/rotate.py index 126534ec2..a1727ff84 100644 --- a/src/keri/app/cli/commands/multisig/rotate.py +++ b/src/keri/app/cli/commands/multisig/rotate.py @@ -7,7 +7,7 @@ import argparse from ordered_set import OrderedSet as oset -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/multisig/update.py b/src/keri/app/cli/commands/multisig/update.py index 4ef7d19fc..f528bcf18 100644 --- a/src/keri/app/cli/commands/multisig/update.py +++ b/src/keri/app/cli/commands/multisig/update.py @@ -6,7 +6,7 @@ import argparse import time -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/oobi/clean.py b/src/keri/app/cli/commands/oobi/clean.py index cd2dc1d46..2dead78d1 100644 --- a/src/keri/app/cli/commands/oobi/clean.py +++ b/src/keri/app/cli/commands/oobi/clean.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/oobi/generate.py b/src/keri/app/cli/commands/oobi/generate.py index f2ac4ba68..2cb0082ee 100644 --- a/src/keri/app/cli/commands/oobi/generate.py +++ b/src/keri/app/cli/commands/oobi/generate.py @@ -7,7 +7,7 @@ from urllib.parse import urlparse import sys -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/oobi/resolve.py b/src/keri/app/cli/commands/oobi/resolve.py index 9b835b30f..b31640e19 100644 --- a/src/keri/app/cli/commands/oobi/resolve.py +++ b/src/keri/app/cli/commands/oobi/resolve.py @@ -5,14 +5,13 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing import keri.app.oobiing from keri.app import habbing, oobiing from keri.app.cli.common import existing from keri.db import basing -from keri.end import ending from keri.help import helping logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/passcode/remove.py b/src/keri/app/cli/commands/passcode/remove.py index 82b6b04f7..68c0aabe2 100644 --- a/src/keri/app/cli/commands/passcode/remove.py +++ b/src/keri/app/cli/commands/passcode/remove.py @@ -5,7 +5,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/passcode/set.py b/src/keri/app/cli/commands/passcode/set.py index a31f978bb..3081a780b 100644 --- a/src/keri/app/cli/commands/passcode/set.py +++ b/src/keri/app/cli/commands/passcode/set.py @@ -6,7 +6,7 @@ import argparse import getpass -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/query.py b/src/keri/app/cli/commands/query.py index dc9a1b220..53e6db690 100644 --- a/src/keri/app/cli/commands/query.py +++ b/src/keri/app/cli/commands/query.py @@ -7,7 +7,7 @@ import datetime import json -from hio import help +from keri import help from hio.base import doing from hio.help import decking diff --git a/src/keri/app/cli/commands/rename.py b/src/keri/app/cli/commands/rename.py index 60fff68ef..7d975d05c 100644 --- a/src/keri/app/cli/commands/rename.py +++ b/src/keri/app/cli/commands/rename.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/rollback.py b/src/keri/app/cli/commands/rollback.py index f7d573f45..1cfce3b7c 100644 --- a/src/keri/app/cli/commands/rollback.py +++ b/src/keri/app/cli/commands/rollback.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/saidify.py b/src/keri/app/cli/commands/saidify.py index 280035fb8..c89fb664b 100644 --- a/src/keri/app/cli/commands/saidify.py +++ b/src/keri/app/cli/commands/saidify.py @@ -6,7 +6,7 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from keri.core import coring diff --git a/src/keri/app/cli/commands/ssh/export.py b/src/keri/app/cli/commands/ssh/export.py index 0f0eff8da..0b45ad472 100644 --- a/src/keri/app/cli/commands/ssh/export.py +++ b/src/keri/app/cli/commands/ssh/export.py @@ -11,7 +11,7 @@ from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import ed25519 -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/status.py b/src/keri/app/cli/commands/status.py index 787bae9ad..130bd50ee 100644 --- a/src/keri/app/cli/commands/status.py +++ b/src/keri/app/cli/commands/status.py @@ -6,11 +6,11 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import displaying, existing -from keri.core import coring, serdering +from keri.core import serdering from keri.kering import ConfigurationError logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/vc/create.py b/src/keri/app/cli/commands/vc/create.py index e30b632dc..7cd815cae 100644 --- a/src/keri/app/cli/commands/vc/create.py +++ b/src/keri/app/cli/commands/vc/create.py @@ -1,7 +1,7 @@ import argparse import json -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/vc/export.py b/src/keri/app/cli/commands/vc/export.py index f79e2b693..d4821dd7b 100644 --- a/src/keri/app/cli/commands/vc/export.py +++ b/src/keri/app/cli/commands/vc/export.py @@ -7,7 +7,7 @@ import argparse import sys -from hio import help +from keri import help from hio.base import doing from keri.app import signing diff --git a/src/keri/app/cli/commands/vc/list.py b/src/keri/app/cli/commands/vc/list.py index 45717c015..d1528b31f 100644 --- a/src/keri/app/cli/commands/vc/list.py +++ b/src/keri/app/cli/commands/vc/list.py @@ -9,7 +9,7 @@ import json import sys -from hio import help +from keri import help from hio.base import doing from keri import kering diff --git a/src/keri/app/cli/commands/vc/registry/incept.py b/src/keri/app/cli/commands/vc/registry/incept.py index 77c774f9a..6b6b3243d 100644 --- a/src/keri/app/cli/commands/vc/registry/incept.py +++ b/src/keri/app/cli/commands/vc/registry/incept.py @@ -1,13 +1,13 @@ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app import indirecting, habbing, grouping, forwarding from keri.app.cli.common import existing from keri.app.habbing import GroupHab from keri.app.notifying import Notifier -from keri.core import coring, serdering +from keri.core import serdering from keri.core.eventing import SealEvent from keri.peer import exchanging from keri.vdr import credentialing diff --git a/src/keri/app/cli/commands/vc/registry/list.py b/src/keri/app/cli/commands/vc/registry/list.py index 3c299895a..90d4c923e 100644 --- a/src/keri/app/cli/commands/vc/registry/list.py +++ b/src/keri/app/cli/commands/vc/registry/list.py @@ -6,7 +6,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app.cli.common import existing diff --git a/src/keri/app/cli/commands/vc/registry/status.py b/src/keri/app/cli/commands/vc/registry/status.py index f24f57a50..55de01ca2 100644 --- a/src/keri/app/cli/commands/vc/registry/status.py +++ b/src/keri/app/cli/commands/vc/registry/status.py @@ -1,11 +1,11 @@ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app import indirecting, habbing, grouping from keri.app.cli.common import existing -from keri.core import coring, serdering +from keri.core import serdering from keri.vdr import credentialing logger = help.ogler.getLogger() diff --git a/src/keri/app/cli/commands/witness/submit.py b/src/keri/app/cli/commands/witness/submit.py index 1aaae2808..652b0541e 100644 --- a/src/keri/app/cli/commands/witness/submit.py +++ b/src/keri/app/cli/commands/witness/submit.py @@ -5,7 +5,7 @@ """ import argparse -from hio import help +from keri import help from hio.base import doing from keri.app import habbing, agenting, indirecting diff --git a/src/keri/app/cli/kli.py b/src/keri/app/cli/kli.py index a3bd13631..a0bde194f 100644 --- a/src/keri/app/cli/kli.py +++ b/src/keri/app/cli/kli.py @@ -4,7 +4,7 @@ """ import multicommand -from hio import help +from keri import help from keri.app import directing from keri.app.cli import commands diff --git a/src/keri/app/delegating.py b/src/keri/app/delegating.py index 107cb2e1b..ff0418ba4 100644 --- a/src/keri/app/delegating.py +++ b/src/keri/app/delegating.py @@ -6,13 +6,13 @@ module for enveloping and forwarding KERI message """ -from hio import help +from keri import help from hio.base import doing from . import agenting, forwarding from .habbing import GroupHab from .. import kering -from ..core import coring, eventing, serdering +from ..core import coring, serdering from ..db import dbing from ..peer import exchanging diff --git a/src/keri/app/forwarding.py b/src/keri/app/forwarding.py index 748a09a6a..b4105b2a1 100644 --- a/src/keri/app/forwarding.py +++ b/src/keri/app/forwarding.py @@ -9,17 +9,18 @@ from ordered_set import OrderedSet as oset from hio.base import doing -from hio.help import decking, ogler +from hio.help import decking from keri import kering from keri.app import agenting from keri.app.habbing import GroupHab +from keri import help from keri.core import coring, eventing, serdering from keri.db import dbing from keri.kering import Roles from keri.peer import exchanging -logger = ogler.getLogger() +logger = help.ogler.getLogger() class Poster(doing.DoDoer): diff --git a/src/keri/demo/demo_kev.py b/src/keri/demo/demo_kev.py index 00b9cca7c..7b125b0a3 100644 --- a/src/keri/demo/demo_kev.py +++ b/src/keri/demo/demo_kev.py @@ -8,11 +8,10 @@ import argparse import logging -from hio import help +from keri import help from hio.base import doing -from ..app import habbing, keeping, apping -from ..db import basing +from ..app import apping logger = help.ogler.getLogger() diff --git a/src/keri/vdr/viring.py b/src/keri/vdr/viring.py index 409b510c2..b57d98e3e 100644 --- a/src/keri/vdr/viring.py +++ b/src/keri/vdr/viring.py @@ -17,12 +17,9 @@ from ..app import signing from ..core import coring, serdering from ..db import dbing, basing -from ..db.dbing import snKey -from ..help import helping -from ..vc import proving from ..vdr import eventing -from hio import help +from keri import help logger = help.ogler.getLogger() diff --git a/tests/help/test_ogling.py b/tests/help/test_ogling.py index 78cd3777d..55ff5521c 100644 --- a/tests/help/test_ogling.py +++ b/tests/help/test_ogling.py @@ -8,7 +8,7 @@ import os import logging -from hio.help import ogling +from keri.help import ogling from keri import help From db467bfd8d548448cacee36cb3fc9ead412e5591 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Tue, 31 Dec 2024 12:36:46 -0700 Subject: [PATCH 46/61] fix: add nonces in prep for private creds (#914) --- src/keri/app/cli/commands/vc/create.py | 19 +++++++++++++++---- src/keri/vc/proving.py | 14 ++++++++------ src/keri/vdr/credentialing.py | 14 ++++++++++---- tests/vc/test_proving.py | 9 +++++---- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/keri/app/cli/commands/vc/create.py b/src/keri/app/cli/commands/vc/create.py index 7cd815cae..ce8c5bf50 100644 --- a/src/keri/app/cli/commands/vc/create.py +++ b/src/keri/app/cli/commands/vc/create.py @@ -1,5 +1,6 @@ import argparse import json +from typing import Optional from keri import help from hio.base import doing @@ -36,6 +37,8 @@ parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', required=True) parser.add_argument("--private", help="flag to indicate if this credential needs privacy preserving features", action="store_true") +parser.add_argument("--private-credential-nonce", help="(str) nonce for vc", action="store") +parser.add_argument("--private-subject-nonce", help="(str) nonce for subject", action="store") parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran parser.add_argument("--time", help="timestamp for the credential creation", required=False, default=None) @@ -99,7 +102,10 @@ def issueCredential(args): rules=rules, credential=credential, timestamp=args.time, - private=args.private) + private=args.private, + private_credential_nonce=args.private_credential_nonce, + private_subject_nonce=args.private_subject_nonce, + ) doers = [issueDoer] return doers @@ -112,7 +118,8 @@ class CredentialIssuer(doing.DoDoer): """ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edges=None, recipient=None, data=None, - rules=None, credential=None, timestamp=None, private=False): + rules=None, credential=None, timestamp=None, private:bool=False, private_credential_nonce:Optional[str]=None, + private_subject_nonce:Optional[str]=None,): """ Create DoDoer for issuing a credential and managing the processes needed to complete issuance Parameters: @@ -124,7 +131,9 @@ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edge data: (dict) credential data dict credential: (dict) full credential to issue when joining a multisig issuance out (str): Filename for credential output - private: (bool) privacy preserving + private (bool): apply nonce used for privacy preserving ACDC + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject """ self.name = name @@ -173,7 +182,9 @@ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edge source=edges, rules=rules, data=data, - private=private) + private=private, + private_credential_nonce=private_credential_nonce, + private_subject_nonce=private_subject_nonce) else: self.creder = serdering.SerderACDC(sad=credential) # proving.Creder(ked=credential) self.credentialer.validate(creder=self.creder) diff --git a/src/keri/vc/proving.py b/src/keri/vc/proving.py index e724648a5..d99f85b4c 100644 --- a/src/keri/vc/proving.py +++ b/src/keri/vc/proving.py @@ -5,7 +5,7 @@ """ from collections.abc import Iterable -from typing import Union +from typing import Union, Optional from .. import help from ..core import coring, serdering @@ -23,8 +23,9 @@ def credential(schema, issuer, data, recipient=None, - private=False, - salt=None, + private: bool = False, + private_credential_nonce: Optional[str] = None, + private_subject_nonce: Optional[str] = None, status=None, source=None, rules=None, @@ -40,7 +41,8 @@ def credential(schema, recipient (Option[str|None]): qb64 identifier prefix of the recipient data (dict): of the values being assigned to the subject of this credential private (bool): apply nonce used for privacy preserving ACDC - salt (string): salt for nonce + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject source (dict | list): of source credentials to which this credential is chained rules (dict | list): ACDC rules section for credential version (Version): version instance @@ -62,8 +64,8 @@ def credential(schema, ) if private: - vc["u"] = salt if salt is not None else coring.Salter().qb64 - subject["u"] = salt if salt is not None else coring.Salter().qb64 + vc["u"] = private_credential_nonce if private_credential_nonce is not None else coring.Salter().qb64 + subject["u"] = private_subject_nonce if private_subject_nonce is not None else coring.Salter().qb64 if recipient is not None: subject['i'] = recipient diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index 8a85c8e54..fd97b8f9e 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -5,6 +5,8 @@ VC issuer support """ +from typing import Optional + from hio.base import doing from hio.help import decking @@ -472,7 +474,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) @@ -770,7 +772,8 @@ def __init__(self, hby, rgy, registrar, verifier): super(Credentialer, self).__init__(doers=doers) - def create(self, regname, recp: str, schema, source, rules, data, private=False): + def create(self, regname, recp: str, schema, source, rules, data, private: bool = False, + private_credential_nonce: Optional[str] = None, private_subject_nonce: Optional[str] = None): """ Create and validate a credential returning the fully populated Creder Parameters: @@ -780,7 +783,9 @@ def create(self, regname, recp: str, schema, source, rules, data, private=False) source: rules: data: - private: add nonce for privacy preserving + private (bool): apply nonce used for privacy preserving ACDC + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject Returns: Creder: Creder class for the issued credential @@ -800,7 +805,8 @@ def create(self, regname, recp: str, schema, source, rules, data, private=False) recipient=recp, data=data, source=source, - private=private, + private_credential_nonce=private_credential_nonce, + private_subject_nonce=private_subject_nonce, rules=rules, status=registry.regk) self.validate(creder) diff --git a/tests/vc/test_proving.py b/tests/vc/test_proving.py index bdb273be1..128209153 100644 --- a/tests/vc/test_proving.py +++ b/tests/vc/test_proving.py @@ -248,18 +248,19 @@ def test_privacy_preserving_credential(mockHelpingNowIso8601): cred = credential(schema="EZllThM1rLBSMZ_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q", recipient="EM_S2MdMaKgP6P2Yyno6-flV6GqrwPencTIw8tCMR7iB", private=True, - salt=salt, + private_credential_nonce=coring.Salter(raw=b'0123456789abcdef').qb64, + private_subject_nonce=coring.Salter(raw=b'abcdef0123456789').qb64, issuer="EMZeK1yLZd1JV6Ktdq_YUt-YbyoTWB9UMcFzuiDly2Y6", data=d, status="ETQoH02zJRCTNz-Wl3nnkUD_RVSzSwcoNvmfa18AWt3M") assert cred.size == len(cred.raw) assert "u" in cred.sad print(cred.raw) - assert cred.raw == (b'{"v":"ACDC10JSON00021c_","d":"ELFOCm58xUlId994cS6m6bsfYOkNHEKoe15Cav-Sj8__",' + assert cred.raw == (b'{"v":"ACDC10JSON00021c_","d":"EMMDzhHHlpQP0XNMRThDeIFkYD1WkDHF7Tp-8kt8X5pn",' b'"u":"0AAwMTIzNDU2Nzg5YWJjZGVm","i":"EMZeK1yLZd1JV6Ktdq_YUt-YbyoTWB9UMcFzuiDl' b'y2Y6","ri":"ETQoH02zJRCTNz-Wl3nnkUD_RVSzSwcoNvmfa18AWt3M","s":"EZllThM1rLBSM' - b'Z_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q","a":{"d":"EFwWs1d_fe_VeLZ0vQQKO-gkRvGrpfWAR' - b'bI4e9tzcqlV","u":"0AAwMTIzNDU2Nzg5YWJjZGVm","i":"EM_S2MdMaKgP6P2Yyno6-flV6Gq' + b'Z_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q","a":{"d":"EK3MRnlg-bMUnHtYKyZ8HD_IbBeI0v4N8' + b'YB4UnNVBqrv","u":"0ABhYmNkZWYwMTIzNDU2Nzg5","i":"EM_S2MdMaKgP6P2Yyno6-flV6Gq' b'rwPencTIw8tCMR7iB","dt":"2021-06-27T21:26:21.233257+00:00","LEI":"254900OPPU' b'84GM83MG36","personLegalName":"John Doe","engagementContextRole":"Project Ma' b'nager"}}') From 247c6e2f52cb425ad899175dcdb3380937615c64 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Thu, 2 Jan 2025 06:51:44 -0700 Subject: [PATCH 47/61] refactor: move escrow logs to TRACE and msg body logs to DEBUG (#913) * refactor: move escrow logs to TRACE and msg body logs to DEBUG * refactor: move some qnf error bodies and TEL success body to debug * refactor: move Likely Duplicitous Event bodies to DEBUG * refactor: add a few more logging changes --- src/keri/core/eventing.py | 646 ++++++++++++++++-------------------- src/keri/core/parsing.py | 25 +- src/keri/core/routing.py | 27 +- src/keri/db/escrowing.py | 29 +- src/keri/help/__init__.py | 12 + src/keri/peer/exchanging.py | 28 +- src/keri/vdr/eventing.py | 60 ++-- src/keri/vdr/verifying.py | 7 +- 8 files changed, 398 insertions(+), 436 deletions(-) diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index 54ab3b72f..591fa9acd 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -7,16 +7,16 @@ import json import logging from collections import namedtuple -from dataclasses import dataclass, astuple, asdict, field +from dataclasses import dataclass, astuple from urllib.parse import urlsplit from math import ceil from ordered_set import OrderedSet as oset from hio.help import decking -from . import coring, serdering -from .coring import (versify, Serials, Ilks, MtrDex, PreDex, DigDex, +from . import coring +from .coring import (versify, Serials, Ilks, PreDex, DigDex, NonTransDex, CtrDex, Counter, - Number, Seqner, Siger, Cigar, Dater, Indexer, IdrDex, + Number, Seqner, Siger, Cigar, Dater, Verfer, Diger, Prefixer, Tholder, Saider) from . import serdering from .. import help @@ -26,14 +26,13 @@ from ..db.dbing import dgKey, snKey, fnKey, splitKeySN, splitKey from ..kering import (MissingEntryError, - ValidationError, DerivationError, MissingSignatureError, + ValidationError, MissingSignatureError, MissingWitnessSignatureError, UnverifiedReplyError, MissingDelegationError, OutOfOrderError, LikelyDuplicitousError, UnverifiedWitnessReceiptError, UnverifiedReceiptError, UnverifiedTransferableReceiptError, QueryNotFoundError) from ..kering import Version, Versionage -from ..kering import (ICP_LABELS, DIP_LABELS, ROT_LABELS, DRT_LABELS, IXN_LABELS, - RPY_LABELS) +from ..kering import (ICP_LABELS, DIP_LABELS, IXN_LABELS) from ..help import helping @@ -2294,9 +2293,12 @@ def valSigsDelWigs(self, serder, sigers, verfers, tholder, self.escrowPSEvent(serder=serder, sigers=sigers, wigers=wigers) if delseqner and delsaider: self.escrowPACouple(serder=serder, seqner=delseqner, saider=delsaider) - raise MissingSignatureError(f"Failure satisfying sith = {tholder.sith}" - f" on sigs for {[siger.qb64 for siger in sigers]}" - f" for evt = {serder.ked}.") + msg=(f"Failure satisfying sith = {tholder.sith} " + f"on sigs {[siger.qb64 for siger in sigers]}" + f"for evt = {serder.said}") + logger.trace(msg) + logger.trace("Event Body=\n%s\n", serder.pretty()) + raise MissingSignatureError(msg) if serder.ilk in (Ilks.rot, Ilks.drt): # rotation so check prior next threshold # prior next threshold in .ntholder and digers in .ndigers @@ -2334,12 +2336,11 @@ def valSigsDelWigs(self, serder, sigers, verfers, tholder, seqner=delseqner, saider=delsaider): # cue to query for witness receipts self.cues.push(dict(kin="query", q=dict(pre=serder.pre, sn=serder.snh))) - raise MissingWitnessSignatureError(f"Failure satisfying toad={toader.num} " - f"on witness sigs=" - f"{[siger.qb64 for siger in wigers]} " - f"for event={serder.ked}.") - - + msg = (f"Failure satisfying toad={toader.num} for event={serder.said}\n" + f"on witness sigs=\n{[siger.qb64 for siger in wigers]}") + logger.trace(msg) + logger.trace("Event Body=\n%s\n", serder.pretty()) + raise MissingWitnessSignatureError(msg) return sigers, delegator, wigers @@ -2701,18 +2702,20 @@ def logEvent(self, serder, sigers=None, wigers=None, wits=None, first=False, if self.cues is not None: # cue to notice BadCloneFN self.cues.push(dict(kin="noticeBadCloneFN", serder=serder, fn=fn, firner=firner, dater=dater)) - logger.info("Kever Mismatch Cloned Replay FN: %s First seen " - "ordinal fn %s and clone fn %s \nEvent=\n%s\n", - serder.preb, fn, firner.sn, serder.pretty()) + logger.info("Kever: Mismatch Cloned Replay FN: First seen " + "ordinal fn %s dig %s and clone fn %s event=%s", + fn, serder.pre, firner.sn, serder.said) + logger.debug("Event Body=\n%s\n", serder.pretty()) if dater: # cloned replay use original's dts from dater dtsb = dater.dtsb self.db.setDts(dgkey, dtsb) # first seen so set dts to now self.db.fons.pin(keys=dgkey, val=Seqner(sn=fn)) - logger.info("Kever state: %s First seen ordinal %s at %s\nEvent=\n%s\n", - serder.preb, fn, dtsb.decode("utf-8"), serder.pretty()) + logger.info("Kever: First seen ordinal %s dig: %s at %s", + fn, serder.pre, dtsb.decode()) + logger.debug("Event Body=\n%s\n", serder.pretty()) self.db.addKe(snKey(serder.preb, serder.sn), serder.saidb) - logger.info("Kever state: %s Added to KEL valid event=\n%s\n", - serder.preb, serder.pretty()) + logger.info("Kever: Added to KEL valid %s event %s for AID %s", serder.ilk, serder.said, serder.pre) + logger.debug("KEL Event Body=\n%s\n", serder.pretty()) return (fn, dtsb.decode("utf-8")) # (fn int, dts str) if first else (None, dts str) def escrowPSEvent(self, serder, sigers, wigers=None): @@ -2733,8 +2736,9 @@ def escrowPSEvent(self, serder, sigers, wigers=None): self.db.putEvt(dgkey, serder.raw) snkey = snKey(serder.preb, serder.sn) self.db.addPse(snkey, serder.saidb) # b'EOWwyMU3XA7RtWdelFt-6waurOTH_aW_Z9VTaU-CshGk.00000000000000000000000000000001' - logger.info("Kever state: Escrowed partially signed or delegated " - "event = %s\n", serder.ked) + logger.info("Kever: Escrowed partially signed or delegated " + "event %s for AID %s", serder.said, serder.pre) + logger.debug("Event Body=\n%s\n", serder.pretty()) def escrowPACouple(self, serder, seqner, saider): """ @@ -2756,7 +2760,8 @@ def escrowPACouple(self, serder, seqner, saider): couple = seqner.qb64b + saider.qb64b self.db.putPde(dgkey, couple) # idempotent logger.info("Kever state: Escrowed source couple for partially signed " - "or delegated event = %s\n", serder.ked) + "or delegated event %s for AID %s", serder.said, serder.pre) + logger.debug("Event Body=\n%s\n", serder.pretty()) def escrowPWEvent(self, serder, wigers, sigers=None, seqner=None, saider=None): """ @@ -2780,8 +2785,8 @@ def escrowPWEvent(self, serder, wigers, sigers=None, seqner=None, saider=None): self.db.putPde(dgkey, couple) self.db.putEvt(dgkey, serder.raw) - logger.info("Kever state: Escrowed partially witnessed " - "event = %s\n", serder.ked) + logger.trace("Kever state: Escrowed partially witnessed event = %s", serder.said) + logger.trace("Event Body=\n%s\n", serder.pretty()) return self.db.addPwe(snKey(serder.preb, serder.sn), serder.saidb) @@ -3203,7 +3208,8 @@ def processEvent(self, serder, sigers, *, wigers=None, else: # escrow likely duplicitous event self.escrowLDEvent(serder=serder, sigers=sigers) - raise LikelyDuplicitousError("Likely Duplicitous event={}.".format(ked)) + logger.debug("Likely Duplicitous event Body=%s", serder.pretty()) + raise LikelyDuplicitousError(f"Likely Duplicitous event={serder.said}") else: # rot, drt, or ixn, so sn matters kever = self.kevers[pre] # get existing kever for pre @@ -3213,7 +3219,8 @@ def processEvent(self, serder, sigers, *, wigers=None, # escrow out-of-order event self.escrowOOEvent(serder=serder, sigers=sigers, seqner=delseqner, saider=delsaider, wigers=wigers) - raise OutOfOrderError("Out-of-order event={}.".format(ked)) + logger.debug("Out of Order event Body=%s", serder.pretty()) + raise OutOfOrderError(f"Out-of-order event={serder.said}") elif ((sn == sno) or # inorder event (ixn, rot, drt) or (ilk == Ilks.rot and # superseding recovery rot or @@ -3275,7 +3282,8 @@ def processEvent(self, serder, sigers, *, wigers=None, else: # escrow likely duplicitous event self.escrowLDEvent(serder=serder, sigers=sigers) - raise LikelyDuplicitousError("Likely Duplicitous event={}.".format(ked)) + logger.debug("Likely Duplicitous event Body=%s", serder.pretty()) + raise LikelyDuplicitousError(f"Likely Duplicitous event={serder.said}") def processReceiptWitness(self, serder, wigers): """ @@ -3329,12 +3337,14 @@ def processReceiptWitness(self, serder, wigers): if not self.lax and wiger.verfer.qb64 in self.prefixes: # own is receiptor if pre in self.prefixes: # skip own receiptor of own event # sign own events not receipt them - logger.info("Kevery process: skipped own receipt attachment" - " on own event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment " + "on own event receipt=%s", serder.said) + logger.debug("Receipt Body=\n%s\n", serder.pretty()) continue # skip own receipt attachment on own event if not self.local: # own receipt on other event when not local - logger.info("Kevery process: skipped own receipt attachment" - " on nonlocal event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment " + "on non-local event receipt=%s", serder.said) + logger.debug("Receipt Body=\n%s\n", serder.pretty()) continue # skip own receipt attachment on non-local event if wiger.verfer.verify(wiger.raw, lserder.raw): @@ -3392,12 +3402,15 @@ def processReceipt(self, serder, cigars): if not self.lax and cigar.verfer.qb64 in self.prefixes: # own is receiptor if pre in self.prefixes: # skip own receipter of own event # sign own events not receipt them - logger.info("Kevery process: skipped own receipt attachment" - " on own event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment " + "on own event receipt=\n%s\n", serder.said) + logger.debug("Receipt Body=\n%s\n", serder.pretty()) continue # skip own receipt attachment on own event if not self.local: # own receipt on other event when not local - logger.info("Kevery process: skipped own receipt attachment" - " on nonlocal event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment " + "on non-local event receipt=%s", serder.said) + logger.debug("Kevery: skipped own receipt attachment " + "on non-local event receipt=\n%s\n", serder.pretty()) continue # skip own receipt attachment on non-local event if cigar.verfer.verify(cigar.raw, lserder.raw): @@ -3460,12 +3473,14 @@ def processReceiptCouples(self, serder, cigars, firner=None): if not self.lax and cigar.verfer.qb64 in self.prefixes: # own is receiptor if pre in self.prefixes: # skip own receipter on own event # sign own events not receipt them - logger.info("Kevery process: skipped own receipt attachment" - " on own event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment" + " on own event receipt=%s", serder.said) + logger.debug("Receipt Body=\n%s\n", serder.pretty()) continue # skip own receipt attachment on own event if not self.local: # own receipt on other event when not local - logger.info("Kevery process: skipped own receipt attachment" - " on nonlocal event receipt=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own receipt attachment" + " on nonlocal event receipt=\n%s\n", serder.said) + logger.debug("Receipt Body=\n%s\n", serder.pretty()) continue # skip own receipt attachment on non-local event if cigar.verfer.verify(cigar.raw, serder.raw): @@ -3508,7 +3523,8 @@ def processReceiptTrans(self, serder, tsgs): if ldig is None: # escrow because event does not yet exist in database # take advantage of fact that receipt and event have same pre, sn fields self.escrowTRGroups(serder, tsgs) - raise UnverifiedTransferableReceiptError("Unverified receipt={}.".format(ked)) + logger.debug("Unverified receipt body=\n%s\n", serder.pretty()) + raise UnverifiedTransferableReceiptError("Unverified receipt=%s", serder.said) # retrieve event by dig assumes if ldig is not None that event exists at ldig ldig = bytes(ldig).decode("utf-8") @@ -3516,18 +3532,18 @@ def processReceiptTrans(self, serder, tsgs): lserder = serdering.SerderKERI(raw=bytes(lraw)) # verify digs match if not lserder.compare(said=ldig): # mismatch events problem with replay - raise ValidationError("Mismatch receipt of event at sn = {} with db." - "".format(sn)) + raise ValidationError(f"Mismatch receipt of event at sn = {sn} with db.") for sprefixer, sseqner, saider, sigers in tsgs: # iterate over each tsg if not self.lax and sprefixer.qb64 in self.prefixes: # own is receipter if pre in self.prefixes: # skip own receipter of own event # sign own events not receipt them - raise ValidationError("Own pre={} receipter of own event" - " {}.".format(self.prefixes, serder.pretty())) + logger.debug("Own pre=%s receiptor of own event \n%s\n", + self.prefixes, serder.pretty()) + raise ValidationError(f"Own pre={self.prefixes} receiptor of own event {serder.said}") if not self.local: # skip own receipts of nonlocal events - raise ValidationError("Own pre={} receipter of nonlocal event " - "{}.".format(self.prefixes, serder.pretty())) + logger.debug("Own pre=%s receiptor of non-local event \n%s\n", serder.prefixes, serder.pretty()) + raise ValidationError(f"Own pre={self.prefixes} receiptor of non-local event {serder.said}") # receipted event in db so attempt to get receipter est evt # retrieve dig of last event at sn of est evt of receipter. @@ -3651,12 +3667,10 @@ def processReceiptQuadruples(self, serder, trqs, firner=None): siger.verfer = sverfers[siger.index] # assign verfer if not siger.verfer.verify(siger.raw, serder.raw): # verify sig - logger.info("Kevery unescrow error: Bad trans receipt sig." - "pre=%s sn=%x receipter=%s\n", pre, sn, sprefixer.qb64) - - raise ValidationError("Bad escrowed trans receipt sig at " - "pre={} sn={:x} receipter={}." - "".format(pre, sn, sprefixer.qb64)) + msg = (f"Kevery unescrow error: Bad escrowed trans receipt sig at " + f"pre={pre} sn={sn:x} receiptor={sprefixer.qb64}") + logger.trace(msg) + raise ValidationError(msg) # good sig so write receipt quadruple to database @@ -3667,10 +3681,12 @@ def processReceiptQuadruples(self, serder, trqs, firner=None): else: # escrow either receiptor or receipted event not yet in database self.escrowTRQuadruple(serder, sprefixer, sseqner, saider, siger) - raise UnverifiedTransferableReceiptError("Unverified receipt: " - "missing associated event for transferable " - "validator receipt quadruple for event={}." - "".format(ked)) + msg = (f"Unverified receipt: " + f"missing associated event for transferable " + f"validator receipt quadruple for event={serder.said}") + logger.info(msg) + logger.debug("Event Body=\n%s\n", serder.pretty()) + raise UnverifiedTransferableReceiptError(msg) def removeStaleReplyEndRole(self, saider): """ @@ -3884,7 +3900,8 @@ def processReplyLocScheme(self, *, serder, saider, route, aid=aid, osaider=osaider, cigars=cigars, tsgs=tsgs) if not accepted: - raise UnverifiedReplyError(f"Unverified loc scheme reply. {serder.ked}") + logger.debug("Unverified loc scheme reply body=\n%s\n", serder.pretty()) + raise UnverifiedReplyError(f"Unverified loc scheme reply for URL {serder.ked['a']['url']}") self.updateLoc(keys=keys, saider=saider, url=url) # update .lans and .locs @@ -4110,18 +4127,21 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None): if pre not in self.kevers: self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error for at route {ked['r']} for evt {ked['d']}") kever = self.kevers[pre] if anchor: if not self.db.findAnchoringSealEvent(pre=pre, seal=anchor): self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error at route {ked['r']} for evt {ked['d']}") elif sn is not None: if kever.sner.num < sn or not self.db.fullyWitnessed(kever.serder): self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error at route {ked['r']} for evt {ked['d']}") msgs = list() # outgoing messages for msg in self.db.clonePreIter(pre=pre, fn=0): @@ -4141,7 +4161,8 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None): if pre not in self.kevers: self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error at route {ked['r']} for evt {ked['d']}") kever = self.kevers[pre] @@ -4151,7 +4172,8 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None): if len(wigers) < kever.toader.num: self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error at route {ked['r']} for evt {ked['d']}") rserder = reply(route=f"/ksn/{src}", data=kever.state()._asdict()) self.cues.push(dict(kin="reply", src=src, route="/ksn", serder=rserder, @@ -4164,7 +4186,8 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None): if pre not in self.kevers: self.escrowQueryNotFoundEvent(serder=serder, prefixer=source, sigers=sigers, cigars=cigars) - raise QueryNotFoundError("Query not found error={}.".format(ked)) + logger.debug("Query not found error. Query Body=%s", ked) + raise QueryNotFoundError(f"Query not found error at route {ked['r']} for evt {ked['d']}") self.cues.push(dict(kin="stream", serder=serder, pre=pre, src=src, topics=topics)) # if pre in self.kevers: @@ -4173,7 +4196,8 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None): # self.cues.push(dict(kin="stream", serder=serder, pre=pre, src=src, topics=topics)) else: self.cues.push(dict(kin="invalid", serder=serder)) - raise ValidationError("invalid query message {} for evt = {}".format(ilk, ked)) + logger.debug("Invalid Query error. Query Body=%s", ked) + raise ValidationError(f"invalid query message {ilk} at route {ked['r']} for evt = {ked['d']}") def fetchEstEvent(self, pre, sn): """ @@ -4227,8 +4251,8 @@ def escrowOOEvent(self, serder, sigers, seqner=None, saider=None, wigers=None): couple = seqner.qb64b + saider.qb64b self.db.putPde(dgkey, couple) # idempotent # log escrowed - logger.info("Kevery process: escrowed out of order event=\n%s\n", - json.dumps(serder.ked, indent=1)) + logger.info("Kevery: escrowed out of order event=\n%s\n", serder.said) + logger.debug("Event Body=\n%s\n", serder.pretty()) def escrowQueryNotFoundEvent(self, prefixer, serder, sigers, cigars=None): """ @@ -4251,8 +4275,8 @@ def escrowQueryNotFoundEvent(self, prefixer, serder, sigers, cigars=None): self.db.addRct(key=dgkey, val=cigar.verfer.qb64b + cigar.qb64b) # log escrowed - logger.info("Kevery process: escrowed query not found event=\n%s\n", - json.dumps(serder.ked, indent=1)) + logger.trace("Kevery: escrowed query not found event = %s", serder.said) + logger.trace("Event Body=\n%s\n", serder.pretty()) def escrowLDEvent(self, serder, sigers): """ @@ -4460,11 +4484,10 @@ def escrowTRQuadruple(self, serder, sprefixer, sseqner, saider, siger): def processEscrows(self): """ - Iterate throush escrows and process any that may now be finalized + Iterate through escrows and process any that may now be finalized Parameters: """ - try: self.processEscrowOutOfOrders() self.processEscrowUnverWitness() @@ -4474,12 +4497,10 @@ def processEscrows(self): self.processEscrowPartialSigs() self.processEscrowDuplicitous() self.processQueryNotFound() - except Exception as ex: # log diagnostics errors etc if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery escrow process error: %s\n", ex.args[0]) - else: - logger.error("Kevery escrow process error: %s\n", ex.args[0]) + logger.trace("Kevery: other escrow process error: %s\n", ex.args[0]) + logger.exception("Kevery other escrow process error: %s\n", ex.args[0]) raise ex def processEscrowOutOfOrders(self): @@ -4529,32 +4550,26 @@ def processEscrowOutOfOrders(self): dtb = self.db.getDts(dgKey(pre, bytes(edig))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery ooo escrow unescrow error: Missing event datetime at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutOOE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery ooo escrow unescrow error: Stale event escrow at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # get the escrowed event using edig eraw = self.db.getEvt(dgKey(pre, bytes(edig))) if eraw is None: # no event so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(edig))) + msg = f"Kevery ooo escrow unescrow error: Missing event at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) eserder = serdering.SerderKERI(raw=bytes(eraw)) # escrowed event @@ -4562,11 +4577,9 @@ def processEscrowOutOfOrders(self): sigs = self.db.getSigs(dgKey(pre, bytes(edig))) if not sigs: # otherwise its a list of sigs # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event sigs at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt sigs at " - "dig = {}.".format(bytes(edig))) + msg = f"Kevery ooo escrow unescrow error: Missing event sigs at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # process event sigers = [Siger(qb64b=bytes(sig)) for sig in sigs] @@ -4593,26 +4606,25 @@ def processEscrowOutOfOrders(self): except OutOfOrderError as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery ooo escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery ooo escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.db.delOoe(snKey(pre, sn), edig) # removes one escrow at key val if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + logger.debug("Kevery: ooo escrow other error on escrow: %s\n", ex.args[0]) + logger.exception("Kevery: ooo escrow other error on : %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delOoe(snKey(pre, sn), edig) # removes one escrow at key val - logger.info("Kevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(eserder.ked, indent=1)) + logger.info("Kevery ooo escrow unescrow succeeded in valid event: " + "key = %s \tdigest = %s", bytes(ekey).decode(), bytes(edig).decode()) + logger.debug("Event Body=\n%s\n", eserder.pretty()) if ekey == key: # still same so no escrows found on last while iteration break @@ -4662,45 +4674,37 @@ def processEscrowPartialSigs(self): dgkey = dgKey(pre, bytes(edig)) # check date if expired then remove escrow. dtb = self.db.getDts(dgkey) - if dtb is None: # othewise is a datetime as bytes - # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(bytes(edig))) + if dtb is None: # otherwise is a datetime as bytes + # no date time so raise ValidationError which unescrows below] + msg = f"Kevery: partial sig escrow unescrow error: Missing event datetime at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutPSE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: partial sig escrow unescrow error: Stale event escrow at dig = {bytes(edig)}", + logger.trace(msg) + raise ValidationError(msg) # get the escrowed event using edig eraw = self.db.getEvt(dgkey) if eraw is None: - # no event so so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(edig))) + # no event so raise ValidationError which unescrows below + msg = f"Kevery: partial sig escrow unescrow error: Missing event at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) eserder = serdering.SerderKERI(raw=bytes(eraw)) # escrowed event # get sigs and attach sigs = self.db.getSigs(dgkey) if not sigs: # otherwise its a list of sigs # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event sigs at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt sigs at " - "dig = {}.".format(bytes(edig))) + msg = f"Kevery: partial sig escrow unescrow error: Missing event sigs at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # seal source (delegator issuer if any) delseqner = delsaider = None @@ -4743,10 +4747,9 @@ def processEscrowPartialSigs(self): except (MissingSignatureError, MissingDelegationError) as ex: # still waiting on missing sigs or missing seal to validate - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: partial sig escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: partial sig escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than waiting on sigs or seal so remove from escrow @@ -4756,9 +4759,8 @@ def processEscrowPartialSigs(self): self.cues.push(dict(kin="psUnescrow", serder=eserder)) if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + logger.trace("Kevery: partial sig escrow other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: partial sig escrow other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be @@ -4770,8 +4772,9 @@ def processEscrowPartialSigs(self): if eserder is not None and eserder.ked["t"] in (Ilks.dip, Ilks.drt,): self.cues.push(dict(kin="psUnescrow", serder=eserder)) - logger.info("Kevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(eserder.ked, indent=1)) + logger.trace("Kevery: partial sig escrow unescrow succeeded in valid event: " + "key = %s \tdigest = %s", bytes(ekey).decode(), bytes(edig).decode()) + logger.trace("Event Body=\n%s\n", json.dumps(eserder.ked, indent=1)) if ekey == key: # still same so no escrows found on last while iteration break @@ -4823,32 +4826,26 @@ def processEscrowPartialWigs(self): dtb = self.db.getDts(dgKey(pre, bytes(edig))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: partial wig escrow unescrow error: Missing event datetime at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutPWE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: partial wig escrow unescrow error: Stale event escrow at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # get the escrowed event using edig eraw = self.db.getEvt(dgKey(pre, bytes(edig))) if eraw is None: # no event so so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(edig))) + msg = f"Kevery: partial wig escrow unescrow error: Missing event at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) eserder = serdering.SerderKERI(raw=bytes(eraw)) # escrowed event @@ -4856,11 +4853,9 @@ def processEscrowPartialWigs(self): sigs = self.db.getSigs(dgKey(pre, bytes(edig))) # list of sigs if not sigs: # empty list # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event sigs at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt sigs at " - "dig = {}.".format(bytes(edig))) + msg = f"Kevery: partial wig escrow unescrow error: Missing event sigs at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # get wigs wigs = self.db.getWigs(dgKey(pre, bytes(edig))) # list of wigs @@ -4870,8 +4865,8 @@ def processEscrowPartialWigs(self): # which may not arrive until some time after event is fully signed # so just log for debugging but do not unescrow by raising # ValidationError - logger.info("Kevery unescrow wigs: No event wigs yet at." - "dig = %s\n", bytes(edig)) + logger.trace("Kevery unescrow wigs: No event wigs yet at." + "dig = %s\n", bytes(edig)) # raise ValidationError("Missing escrowed evt wigs at " # "dig = {}.".format(bytes(edig))) @@ -4908,26 +4903,25 @@ def processEscrowPartialWigs(self): except MissingWitnessSignatureError as ex: # still waiting on missing witness sigs - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: partial wig escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: partial wig escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than waiting on sigs or seal so remove from escrow self.db.delPwe(snKey(pre, sn), edig) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: partial wig escrow other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: partial wig escrow other error unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delPwe(snKey(pre, sn), edig) # removes one escrow at key val - logger.info("Kevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(eserder.ked, indent=1)) + logger.trace("Kevery: partial wig escrow unescrow succeeded in valid event: " + "key = %s \tdigest = %s", bytes(ekey).decode(), bytes(edig).decode()) + logger.trace("Event Body=\n%s\n", json.dumps(eserder.ked, indent=1)) if ekey == key: # still same so no escrows found on last while iteration break @@ -4996,22 +4990,18 @@ def processEscrowUnverWitness(self): dtb = self.db.getDts(dgKey(pre, bytes(rdiger.qb64b))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", rdiger.qb64b) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(rdiger.qb64b)) + msg = f"Kevery: unver wit escrow unescrow error: Missing event datetime at dig = {rdiger.qb64}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutUWE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", rdiger.qb64b) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(rdiger.qb64b)) + msg = f"Kevery: unver wit escrow unescrow error: Stale event escrow at dig = {rdiger.qb64}" + logger.trace(msg) + raise ValidationError(msg) # lookup database dig of the receipted event in pwes escrow # using pre and sn lastEvt @@ -5022,34 +5012,31 @@ def processEscrowUnverWitness(self): if not found: # no partial witness escrow of event found # so keep in escrow by raising UnverifiedWitnessReceiptError - logger.info("Kevery unescrow error: Missing witness " - "receipted evt at pre=%s sn=%x\n", (pre, sn)) - - raise UnverifiedWitnessReceiptError("Missing witness " - "receipted evt at pre={} sn={:x}".format(pre, sn)) + msg = (f"Kevery: unver wit escrow unescrow error: " + f"Missing witness receipted evt at pre={pre} sn={sn:x}") + logger.trace(msg) + raise UnverifiedWitnessReceiptError(msg) except UnverifiedWitnessReceiptError as ex: # still waiting on missing prior event to validate # only happens if we process above - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver wit escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: unver wit escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.db.delUwe(snKey(pre, sn), ecouple) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver wit escrow other unescrow error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: unver wit escrow other unescrow error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delUwe(snKey(pre, sn), ecouple) # removes one escrow at key val - logger.info("Kevery unescrow succeeded for event pre=%s " + logger.info("Kevery: unver wit escrow unescrow succeeded for event pre=%s " "sn=%s\n", pre, sn) if ekey == key: # still same so no escrows found on last while iteration @@ -5116,22 +5103,20 @@ def processEscrowUnverNonTrans(self): dtb = self.db.getDts(dgKey(pre, bytes(rsaider.qb64b))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", rsaider.qb64b) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(rsaider.qb64b)) + msg = (f"Kevery: unver nontrans escrow unescrow error: " + f"Missing event datetime at dig = {rsaider.qb64}") + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutURE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", rsaider.qb64b) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(rsaider.qb64b)) + msg = (f"Kevery: unver nontrans escrow unescrow error: " + f"Stale event escrow at dig = {rsaider.qb64}") + logger.trace(msg) + raise ValidationError(msg) # Is receipt for unverified witnessed event in .Pwes escrow # if found then try else clause will remove from escrow @@ -5148,41 +5133,35 @@ def processEscrowUnverNonTrans(self): dig = self.db.getKeLast(snKey(pre, sn)) if dig is None: # no receipted event so keep in escrow - logger.info("Kevery unescrow error: Missing receipted " - "event at pre=%s sn=%x\n", pre, sn) - - raise UnverifiedReceiptError("Missing receipted evt " - "at pre={} sn={:x}".format(pre, sn)) + msg = (f"Kevery: unver nontrans escrow unescrow error: " + f"Missing receipted evt at pre={pre} sn={sn:x}") + logger.trace(msg) + raise UnverifiedReceiptError(msg) # get receipted event using pre and edig raw = self.db.getEvt(dgKey(pre, dig)) if raw is None: # receipted event superseded so remove from escrow - logger.info("Kevery unescrow error: Invalid receipted " - "event refereance at pre=%s sn=%x\n", pre, sn) - - raise ValidationError("Invalid receipted evt reference" - " at pre={} sn={:x}".format(pre, sn)) + msg = (f"Kevery: unver nontrans escrow unescrow error: " + f"Invalid receipted event reference at pre={pre} sn={sn:x}") + logger.trace(msg) + raise ValidationError(msg) serder = serdering.SerderKERI(raw=bytes(raw)) # receipted event # compare digs if rsaider.qb64b != serder.saidb: - logger.info("Kevery unescrow error: Bad receipt dig." - "pre=%s sn=%x receipter=%s\n", pre, sn, sprefixer.qb64) - - raise ValidationError("Bad escrowed receipt dig at " - "pre={} sn={:x} receipter={}." - "".format(pre, sn, sprefixer.qb64)) + msg = (f"Kevery: unver nontrans escrow unescrow error: Bad receipt dig" + f"pre={pre} sn={sn:x} receiptor={sprefixer.qb64}") + logger.trace(msg) + raise ValidationError(msg) # verify sig verfer key is prefixer from triple if not cigar.verfer.verify(cigar.raw, serder.raw): # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Bad receipt sig." - "pre=%s sn=%x receipter=%s\n", pre, sn, sprefixer.qb64) - - raise ValidationError("Bad escrowed receipt sig at " - "pre={} sn={:x} receipter={}." - "".format(pre, sn, sprefixer.qb64)) + msg = (f"Kevery: unver nontrans escrow unescrow error: " + f"Bad receipt sig at pre={pre} sn={sn:x} receiptor={sprefixer.qb64}") + logger.trace(msg) + raise ValidationError(msg) # get current wits from kever state assuming not stale # receipt. Need function here to compute wits for actual @@ -5204,25 +5183,23 @@ def processEscrowUnverNonTrans(self): except UnverifiedReceiptError as ex: # still waiting on missing prior event to validate # only happens if we process above - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver nontrans escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: unver nontrans escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.db.delUre(snKey(pre, sn), etriplet) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver nontrans escrow other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: unver nontrans escrow other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delUre(snKey(pre, sn), etriplet) # removes one escrow at key val - logger.info("Kevery unescrow succeeded for event pre=%s " + logger.info("Kevery: unver nontrans escrow unescrow succeeded for event pre=%s " "sn=%s\n", pre, sn) if ekey == key: # still same so no escrows found on last while iteration @@ -5265,32 +5242,26 @@ def processQueryNotFound(self): dtb = self.db.getDts(dgKey(pre, bytes(edig))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: qnf escrow unescrow error: Missing event datetime at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutQNF): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale qry event escrow " - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Stale qry event escrow " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: qnf escrow unescrow error: Stale qry event escrow at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # get the escrowed event using edig eraw = self.db.getEvt(dgKey(pre, bytes(edig))) if eraw is None: # no event so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(edig))) + msg = f"Kevery: qnf escrow unescrow error: Missing event at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) eserder = serdering.SerderKERI(raw=bytes(eraw)) # escrowed event @@ -5298,11 +5269,9 @@ def processQueryNotFound(self): sigs = self.db.getSigs(dgKey(pre, bytes(edig))) if not sigs: # otherwise its a list of sigs # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event sigs at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt sigs at " - "dig = {}.".format(bytes(edig))) + msg = f"Kevery: qnf escrow unescrow error: Missing event sigs at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # process event sigers = [Siger(qb64b=bytes(sig)) for sig in sigs] @@ -5319,25 +5288,24 @@ def processQueryNotFound(self): except QueryNotFoundError as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: qnf escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: qnf escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.db.delQnf(dgKey(pre, edig), edig) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: qnf other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: qnf other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delQnf(dgKey(pre, edig), edig) # removes one escrow at key val - logger.info("Kevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(eserder.ked, indent=1)) + logger.info("Kevery: qnf unescrow succeeded in valid event: " + "key = %s \tdigest = %s", bytes(ekey).decode(), bytes(edig).decode()) + logger.debug("Event Body=\n%s\n", eserder.pretty()) if ekey == key: # still same so no escrows found on last while iteration break @@ -5428,10 +5396,10 @@ def _processEscrowFindUnver(self, pre, sn, rsaider, wiger=None, cigar=None): elif wiger: # check index and assign verfier to wiger if wiger.index >= len(wits): # bad index # raise ValidationError which removes from escrow by caller - logger.info("Kevery unescrow error: Bad witness receipt" - " index=%i for pre=%s sn=%x\n", wiger.index, pre, sn) - raise ValidationError("Bad escrowed witness receipt index={}" - " at pre={} sn={:x}.".format(wiger.index, pre, sn)) + msg = (f"Kevery: find unver escrow unescrow error: Bad escrowed witness receipt" + f" index={wiger.index:i} for pre={pre} sn={sn:x}") + logger.trace(msg) + raise ValidationError(msg) wiger.verfer = Verfer(qb64=wits[wiger.index]) found = True @@ -5440,12 +5408,10 @@ def _processEscrowFindUnver(self, pre, sn, rsaider, wiger=None, cigar=None): if found: # verify signature and if verified write to .Wigs if not wiger.verfer.verify(wiger.raw, serder.raw): # not verify # raise ValidationError which unescrows .Uwes or .Ures in caller - logger.info("Kevery unescrow error: Bad witness receipt" - " wig. pre=%s sn=%x\n", pre, sn) - - raise ValidationError("Bad escrowed witness receipt wig" - " at pre={} sn={:x}." - "".format(pre, sn)) + msg = (f"Kevery: find unver escrow unescrow error: Bad witness receipt wig." + f" pre={pre} sn={sn:x}") + logger.trace(msg) + raise ValidationError(msg) self.db.addWig(key=dgKey(pre, serder.said), val=wiger.qb64b) # processEscrowPartialWigs removes from this .Pwes escrow # when fully witnessed using self.db.delPwe(snkey, dig) @@ -5509,53 +5475,44 @@ def processEscrowUnverTrans(self): dtb = self.db.getDts(dgKey(pre, bytes(esaider.qb64b))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", esaider.qb64b) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(esaider.qb64b)) + msg = f"Kevery: unver trans escrow unescrow error: Missing event datetime at dig = {esaider.qb64}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutVRE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", esaider.qb64b) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(esaider.qb64b)) + msg = f"Kevery: unver trans escrow unescrow error: Stale event escrow at dig = {esaider.qb64}" + logger.info(msg) + raise ValidationError(msg) # get dig of the receipted event using pre and sn lastEvt raw = self.db.getKeLast(snKey(pre, sn)) if raw is None: # no event so keep in escrow - logger.info("Kevery unescrow error: Missing receipted " - "event at pre=%s sn=%x\n", pre, sn) - - raise UnverifiedTransferableReceiptError("Missing receipted evt at pre={} " - " sn={:x}".format(pre, sn)) + msg = f"Kevery: unver trans escrow unescrow error: Missing receipted event at pre={pre} sn={sn:x}" + logger.trace(msg) + raise UnverifiedTransferableReceiptError(msg) dig = bytes(raw) # get receipted event using pre and edig raw = self.db.getEvt(dgKey(pre, dig)) if raw is None: # receipted event superseded so remove from escrow - logger.info("Kevery unescrow error: Invalid receipted " - "event referenace at pre=%s sn=%x\n", pre, sn) - - raise ValidationError("Invalid receipted evt reference " - "at pre={} sn={:x}".format(pre, sn)) + msg = (f"Kevery: unver trans escrow unescrow error: Invalid receipted " + f"event reference at pre={pre} sn={sn:x}") + logger.trace(msg) + raise ValidationError(msg) serder = serdering.SerderKERI(raw=bytes(raw)) # receipted event # compare digs if esaider.qb64b != serder.saidb: - logger.info("Kevery unescrow error: Bad receipt dig." - "pre=%s sn=%x receipter=%s\n", (pre, sn, sprefixer.qb64)) - - raise ValidationError("Bad escrowed receipt dig at " - "pre={} sn={:x} receipter={}." - "".format(pre, sn, sprefixer.qb64)) + msg = (f"Kevery: unver trans escrow unescrow error: Bad escrowed receipt dig at " + f"pre={pre} sn={sn:x} receipter={sprefixer.qb64}") + logger.trace(msg) + raise ValidationError(msg) # get receipter's last est event # retrieve dig of last event at sn of receipter. @@ -5563,11 +5520,9 @@ def processEscrowUnverTrans(self): sn=sseqner.sn)) if sdig is None: # no event so keep in escrow - logger.info("Kevery unescrow error: Missing receipted " - "event at pre=%s sn=%x\n", pre, sn) - - raise UnverifiedTransferableReceiptError("Missing receipted evt at pre={} " - " sn={:x}".format(pre, sn)) + msg = f"Kevery: unver trans escrow unescrow error: Missing receipted evt at pre={pre} sn={sn:x}" + logger.trace(msg) + raise UnverifiedTransferableReceiptError(msg) # retrieve last event itself of receipter sraw = self.db.getEvt(key=dgKey(pre=sprefixer.qb64b, dig=bytes(sdig))) @@ -5594,12 +5549,10 @@ def processEscrowUnverTrans(self): siger.verfer = verfers[siger.index] # assign verfer if not siger.verfer.verify(siger.raw, serder.raw): # verify sig - logger.info("Kevery unescrow error: Bad trans receipt sig." - "pre=%s sn=%x receipter=%s\n", pre, sn, sprefixer.qb64) - - raise ValidationError("Bad escrowed trans receipt sig at " - "pre={} sn={:x} receipter={}." - "".format(pre, sn, sprefixer.qb64)) + msg = (f"Kevery: unver trans escrow unescrow error: bad escrowed trans receipt sig at " + f"pre={pre} sn={sn:x} receipter={sprefixer.qb64}.") + logger.trace(msg) + raise ValidationError(msg) # good sig so write receipt quadruple to database quadruple = sealet + siger.qb64b @@ -5609,25 +5562,23 @@ def processEscrowUnverTrans(self): except UnverifiedTransferableReceiptError as ex: # still waiting on missing prior event to validate # only happens if we process above - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver trans escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: unver trans escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.db.delVre(snKey(pre, sn), equinlet) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): # adds exception data - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): # adds exception data + logger.trace("Kevery: unver trans escrow other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: unver trans escrow other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delVre(snKey(pre, sn), equinlet) # removes one escrow at key val - logger.info("Kevery unescrow succeeded for event = %s\n", serder.ked) + logger.info("Kevery: unver trans escrow unescrow succeeded for event = %s\n", serder.ked) if ekey == key: # still same so no escrows found on last while iteration break @@ -5678,32 +5629,26 @@ def processEscrowDuplicitous(self): dtb = self.db.getDts(dgKey(pre, bytes(edig))) if dtb is None: # othewise is a datetime as bytes # no date time so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event datetime" - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed event datetime " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: duplicity escrow unescrow error: Missing event datetime at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # do date math here and discard if stale nowIso8601() bytes dtnow = helping.nowUTC() dte = helping.fromIso8601(bytes(dtb)) if (dtnow - dte) > datetime.timedelta(seconds=self.TimeoutLDE): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale event escrow " - " at dig = %s\n", bytes(edig)) - - raise ValidationError("Stale event escrow " - "at dig = {}.".format(bytes(edig))) + msg = f"Kevery: duplicity escrow unescrow error: Stale event escrow at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) # get the escrowed event using edig eraw = self.db.getEvt(dgKey(pre, bytes(edig))) if eraw is None: # no event so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(edig))) + msg = f"Kevery: duplicity escrow unescrow error: Missing event at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) eserder = serdering.SerderKERI(raw=bytes(eraw)) # escrowed event @@ -5711,11 +5656,9 @@ def processEscrowDuplicitous(self): sigs = self.db.getSigs(dgKey(pre, bytes(edig))) if not sigs: # otherwise its a list of sigs # no sigs so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Missing event sigs at." - "dig = %s\n", bytes(edig)) - - raise ValidationError("Missing escrowed evt sigs at " - "dig = {}.".format(bytes(edig))) + msg = f"Kevery: duplicity escrow unescrow error: Missing event sigs at dig = {bytes(edig)}" + logger.trace(msg) + raise ValidationError(msg) sigers = [Siger(qb64b=bytes(sig)) for sig in sigs] self.processEvent(serder=eserder, sigers=sigers) @@ -5736,26 +5679,25 @@ def processEscrowDuplicitous(self): except LikelyDuplicitousError as ex: # still can't determine if duplicitous - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: duplicity escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Kevery: duplicity escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than likely duplicitous so remove from escrow self.db.delLde(snKey(pre, sn), edig) # removes one escrow at key val - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrowed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery: duplicity escrow other error on unescrow: %s\n", ex.args[0]) + logger.exception("Kevery: duplicity escrow other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delLde(snKey(pre, sn), edig) # removes one escrow at key val - logger.info("Kevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(eserder.ked, indent=1)) + logger.info("Kevery: duplicity escrow unescrow succeeded in valid event: " + "key = %s \tdigest = %s", bytes(ekey).decode(), bytes(edig).decode()) + logger.debug("Event Body=\n%s\n", eserder.pretty()) if ekey == key: # still same so no escrows found on last while iteration break diff --git a/src/keri/core/parsing.py b/src/keri/core/parsing.py index e3f18bb9f..2b4798dbe 100644 --- a/src/keri/core/parsing.py +++ b/src/keri/core/parsing.py @@ -6,7 +6,6 @@ """ import logging -import traceback from collections import namedtuple from dataclasses import dataclass, astuple @@ -1020,8 +1019,8 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, # when present assumes this is source seal of delegating event in delegator's KEL delseqner, delsaider = sscs[-1] if sscs else (None, None) # use last one if more than one if not sigers: - raise kering.ValidationError("Missing attached signature(s) for evt " - "= {}.".format(serder.ked)) + logger.debug("Parser: Missing attached signature(s) for evt = \n%s\n", serder.ked) + raise kering.ValidationError(f"Missing attached signature(s) for evt={serder.ked['d']}") try: kvy.processEvent(serder=serder, sigers=sigers, @@ -1037,13 +1036,13 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, kvy.processReceiptQuadruples(serder, trqs, firner=firner) except AttributeError as ex: - raise kering.ValidationError("No kevery to process so dropped msg" - "= {}.".format(serder.pretty())) from ex + logger.debug("Parser: No kevery to process so dropped msg = %s", serder.pretty()) + raise kering.ValidationError(f"No kevery to process so dropped msg={serder.ked['d']}") from ex elif ilk in [Ilks.rct]: # event receipt msg (nontransferable) if not (cigars or wigers or tsgs): - raise kering.ValidationError("Missing attached signatures on receipt" - "msg = {}.".format(serder.ked)) + logger.debug("Parser: Missing attached signatures on receipt msg = %s.", serder.ked) + raise kering.ValidationError(f"Missing attached sigs on receipt msg={serder.ked['d']}") try: if cigars: @@ -1074,6 +1073,12 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, except AttributeError as e: raise kering.ValidationError("No kevery to process so dropped msg" "= {}.".format(serder.pretty())) + except kering.UnverifiedReplyError as e: + if logger.isEnabledFor(logging.DEBUG): + logger.exception("Error processing reply = %s", e) + logger.debug("Reply Body=\n%s\n", serder.pretty()) + else: + logger.error("Error processing reply = %s", e) elif ilk in (Ilks.qry,): # query message args = dict(serder=serder) @@ -1096,6 +1101,12 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, except AttributeError: raise kering.ValidationError("No kevery to process so dropped msg" "= {}.".format(serder.pretty())) + except kering.QueryNotFoundError as e: # catch escrow error and log it + if logger.isEnabledFor(logging.TRACE): + logger.exception("Error processing query = %s", e) + logger.trace("Query Body=\n%s\n", serder.pretty()) + else: + logger.error("Error processing query = %s", e) elif route in ["tels", "tsn"]: try: diff --git a/src/keri/core/routing.py b/src/keri/core/routing.py index c67092b65..f335b074a 100644 --- a/src/keri/core/routing.py +++ b/src/keri/core/routing.py @@ -183,7 +183,7 @@ def processReply(self, serder, cigars=None, tsgs=None): Escrow process logic is route dependent and is dispatched by route, i.e. route is address of buffer with route specific handler of escrow. """ - for k in eventing.RPY_LABELS: + for k in kering.RPY_LABELS: if k not in serder.ked: raise kering.ValidationError(f"Missing element={k} from {coring.Ilks.rpy}" f" msg={serder.ked}.") @@ -265,26 +265,30 @@ def acceptReply(self, serder, saider, route, aid, osaider=None, if not self.lax and cigar.verfer.qb64 in self.prefixes: # own cig if not self.local: # own cig when not local so ignore - logger.info("Kevery process: skipped own attachment" - " on nonlocal reply msg=\n%s\n", serder.pretty()) + logger.info("Kevery: skipped own attachment for AID %s" + " on non-local reply at route = %s", aid, serder.ked['r']) + logger.debug("Reply Body=\n%s\n", serder.pretty()) continue # skip own cig attachment on non-local reply msg if aid != cigar.verfer.qb64: # cig not by aid - logger.info("Kevery process: skipped cig not from aid=" - "%s on reply msg=\n%s\n", aid, serder.pretty()) + logger.info("Kevery: skipped cig not from aid=" + "%s on reply at route %s", aid, serder.ked['r']) + logger.debug("Reply Body=\n%s\n", serder.pretty()) continue # skip invalid cig's verfer is not aid if odater: # get old compare datetimes to see if later if dater.datetime <= odater.datetime: - logger.info("Kevery process: skipped stale update from " - "%s of reply msg=\n%s\n", aid, serder.pretty()) + logger.trace("Kevery: skipped stale update from " + "%s of reply at route= %s", aid, serder.ked['r']) + logger.trace("Reply Body=\n%s\n", serder.pretty()) continue # skip if not later # raise ValidationError(f"Stale update of {route} from {aid} " # f"via {Ilks.rpy}={serder.ked}.") if not cigar.verfer.verify(cigar.raw, serder.raw): # cig not verify - logger.info("Kevery process: skipped nonverifying cig from " - "%s on reply msg=\n%s\n", cigar.verfer.qb64, serder.pretty()) + logger.info("Kevery: skipped non-verifying cig from " + "%s on reply at route = %s", cigar.verfer.qb64, serder.ked['r']) + logger.debug("Reply Body=\n%s\n", serder.pretty()) continue # skip if cig not verify # All constraints satisfied so update @@ -482,10 +486,9 @@ def processEscrowReply(self): except kering.UnverifiedReplyError as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): + if logger.isEnabledFor(logging.TRACE): + logger.trace("Kevery unescrow attempt failed: %s\n", ex.args[0]) logger.exception("Kevery unescrow attempt failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow attempt failed: %s\n", ex.args[0]) except Exception as ex: # other error so remove from reply escrow self.db.rpes.rem(keys=(route, ), val=saider) # remove escrow only diff --git a/src/keri/db/escrowing.py b/src/keri/db/escrowing.py index a2a886238..ff6fd5268 100644 --- a/src/keri/db/escrowing.py +++ b/src/keri/db/escrowing.py @@ -88,7 +88,7 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): try: if not (dater and serder and (tsgs or vcigars)): - raise ValueError(f"Missing escrow artifacts at said={saider.qb64}" + raise ValueError(f"Broker: Missing escrow artifacts at said={saider.qb64}" f"for pre={pre}.") cigars = [] @@ -101,40 +101,39 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): if ((helping.nowUTC() - dater.datetime) > datetime.timedelta(seconds=self.timeout)): # escrow stale so raise ValidationError which unescrows below - logger.info("Kevery unescrow error: Stale txn state escrow " - " at pre = %s\n", pre) - - raise kering.ValidationError(f"Stale txn state escrow at pre = {pre}.") + msg = f"Broker: {typ} escrow unescrow error: Stale txn state escrow at pre = {pre}" + logger.trace(msg) + raise kering.ValidationError(msg) processReply(serder=serder, saider=saider, route=serder.ked["r"], cigars=cigars, tsgs=tsgs, aid=aid) except extype as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrow attempt failed: %s\n", ex.args[0]) - else: - logger.error("Kevery unescrow attempt failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Broker: %s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) + logger.exception("Broker: %s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) except Exception as ex: # other error so remove from reply escrow self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed due to error: %s\n", ex.args[0]) + logger.exception("Broker: %s escrow other error on unescrow: %s\n", typ, ex.args[0]) else: - logger.error("Kevery unescrowed due to error: %s\n", ex.args[0]) + logger.error("Broker: %s escrow other error on unescrow: %s\n", typ, ex.args[0]) else: # unescrow succeded self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow only - logger.info("Kevery unescrow succeeded for txn state=\n%s\n", - serder.pretty()) + logger.info("Broker: %s escrow unescrow succeeded for txn state=%s", + typ, serder.said) + logger.debug("TXN State Body=\n%s\n", serder.pretty()) except Exception as ex: # log diagnostics errors etc self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow self.removeState(saider) if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery unescrowed due to error: %s\n", ex.args[0]) + logger.exception("Broker: %s escrow unescrowed due to error: %s\n", typ, ex.args[0]) else: - logger.error("Kevery unescrowed due to error: %s\n", ex.args[0]) + logger.error("Broker: %s escrow unescrowed due to error: %s\n", typ, ex.args[0]) def escrowStateNotice(self, *, typ, pre, aid, serder, saider, dater, cigars=None, tsgs=None): """ diff --git a/src/keri/help/__init__.py b/src/keri/help/__init__.py index 72f5f27eb..6922651ad 100644 --- a/src/keri/help/__init__.py +++ b/src/keri/help/__init__.py @@ -13,6 +13,18 @@ from hio.help import ogling +import logging + +# Custom TRACE log level configuration +TRACE = 5 # TRACE (5) logging level value between DEBUG (10) and NOTSET (0) +logging.TRACE = TRACE # add TRACE logging level to logging module +logging.addLevelName(logging.TRACE, "TRACE") +def trace(self, message, *args, **kwargs): + """Trace logging function - logs message if TRACE (5) level enabled""" + if self.isEnabledFor(TRACE): + self._log(TRACE, message, args, **kwargs) +logging.Logger.trace = trace + # want help.ogler always defined by default ogler = ogling.initOgler(prefix='keri', syslogged=False) # inits once only on first import diff --git a/src/keri/peer/exchanging.py b/src/keri/peer/exchanging.py index 0ab215956..1b100d66d 100644 --- a/src/keri/peer/exchanging.py +++ b/src/keri/peer/exchanging.py @@ -121,11 +121,12 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): # Perform behavior specific verification, think IPEX chaining requirements try: if not behavior.verify(serder=serder, attachments=attachments): - logger.info(f"exn event for route {route} failed behavior verfication. exn={serder.ked}") + logger.info(f"exn event for route {route} failed behavior verification. exn={serder.said}") + logger.debug(f"exn body=\n{serder.ked}\n") return - except AttributeError: - logger.info(f"Behavior for {route} missing or does not have verify for exn={serder.ked}") + logger.debug(f"Behavior for {route} missing or does not have verify for exn={serder.said}") + logger.debug(f"exn Body=\n{serder.ked}\n") # Always persis events self.logEvent(serder, pathed, tsgs, cigars) @@ -135,7 +136,9 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): try: behavior.handle(serder=serder, attachments=attachments) except AttributeError: - logger.info(f"Behavior for {route} missing or does not have handle for exn={serder.ked}") + logger.info(f"Behavior for {route} missing or does not have handle for exn={serder.said}") + logger.debug( + f"exn body=\n{serder.ked}\n") def processEscrow(self): """ Process all escrows for `exn` messages @@ -187,24 +190,21 @@ def processEscrowPartialSigned(self): try: self.processEvent(serder=serder, tsgs=tsgs, pathed=pathed) - except MissingSignatureError as ex: - if logger.isEnabledFor(logging.DEBUG): - logger.info("Exchange partially signed unescrow failed: %s\n", ex.args[0]) - else: - logger.info("Exchange partially signed failed: %s\n", ex.args[0]) + logger.trace("Exchange partially signed unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.debug(f"Event body=\n{serder.pretty()}\n") except Exception as ex: self.hby.db.epse.rem(dig) self.hby.db.esigs.rem(dig) + logger.info("Exchange partially signed unescrowed: %s\n", ex.args[0]) if logger.isEnabledFor(logging.DEBUG): - logger.info("Exchange partially signed unescrowed: %s\n", ex.args[0]) - else: - logger.info("Exchange partially signed unescrowed: %s\n", ex.args[0]) + logger.debug(f"Event body=\n{serder.pretty()}\n") else: self.hby.db.epse.rem(dig) self.hby.db.esigs.rem(dig) - logger.info("Exchanger unescrow succeeded in valid exchange: " - "creder=\n%s\n", serder.pretty()) + logger.info(f"Exchanger unescrow succeeded in valid exchange: serder={serder.said}") + logger.debug(f"Serder Body=\n{serder.pretty()}\n") def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): dig = serder.said diff --git a/src/keri/vdr/eventing.py b/src/keri/vdr/eventing.py index 063ebaad7..030ce18be 100644 --- a/src/keri/vdr/eventing.py +++ b/src/keri/vdr/eventing.py @@ -1267,8 +1267,8 @@ def logEvent(self, pre, sn, serder, seqner, saider, bigers=None, baks=None): self.reger.tets.pin(keys=(pre.decode("utf-8"), dig.decode("utf-8")), val=coring.Dater()) self.reger.putTvt(key, serder.raw) self.reger.putTel(snKey(pre, sn), dig) - logger.info("Tever state: %s Added to TEL valid event=\n%s\n", - pre, json.dumps(serder.ked, indent=1)) + logger.info("Tever: Added to TEL valid %s event=%s for AID %s", serder.ilk, serder.said, serder.pre) + logger.debug("TEL Event Body=\n%s\n", serder.pretty()) def valAnchorBigs(self, serder, seqner, saider, bigers, toad, baks): """ Validate anchor and backer signatures (bigers) when provided. @@ -1319,12 +1319,12 @@ def valAnchorBigs(self, serder, seqner, saider, bigers, toad, baks): if len(bindices) < toad: # not fully witnessed yet self.escrowPWEvent(serder=serder, seqner=seqner, saider=saider, bigers=bigers) - - raise MissingWitnessSignatureError("Failure satisfying toad = {} " - "on witness sigs for {} for evt = {}.".format(toad, - [siger.qb64 for siger - in bigers], - serder.ked)) + msg = (f"Failure satisfying toad={toad} on witness sigs " + f"for {[siger.qb64 for siger in bigers]} " + f"for evt = {serder.said}.") + logger.info(msg) + logger.debug(f"Event Body=\n{serder.ked}\n") + raise MissingWitnessSignatureError(msg) return bigers def verifyAnchor(self, serder, seqner=None, saider=None): @@ -1588,7 +1588,8 @@ def processEvent(self, serder, seqner=None, saider=None, wigers=None): if ilk in (Ilks.vcp,): # we don't have multiple signatures to verify so this # is already first seen and then lifely duplicitious - raise LikelyDuplicitousError("Likely Duplicitous event={}.".format(ked)) + logger.debug("Likely Duplicitous event Body=%s", serder.pretty()) + raise LikelyDuplicitousError(f"Likely Duplicitous event={serder.said}") tever = self.tevers[regk] tever.cues = self.cues @@ -1614,7 +1615,8 @@ def processEvent(self, serder, seqner=None, saider=None, wigers=None): # self.cues.append(dict(kin="receipt", serder=serder)) pass else: # duplicitious - raise LikelyDuplicitousError("Likely Duplicitous event={} with sn {}.".format(ked, sn)) + logger.debug("Likely Duplicitous event Body=%s", serder.pretty()) + raise LikelyDuplicitousError(f"Likely Duplicitous event={serder.said} with sn {serder.sn}") def processQuery(self, serder, source=None, sigers=None, cigars=None): """ Process TEL query event message (qry) @@ -2077,10 +2079,9 @@ def processEscrowOutOfOrders(self): except OutOfOrderError as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): + if logger.isEnabledFor(logging.TRACE): + logger.trace("Tevery unescrow failed: %s\n", ex.args[0]) logger.exception("Tevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Tevery unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -2096,7 +2097,7 @@ def processEscrowOutOfOrders(self): # valid event escrow. self.reger.delOot(snKey(pre, sn)) # removes from escrow logger.info("Tevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(tserder.ked, indent=1)) + "event=\n%s\n", tserder.pretty()) def processEscrowAnchorless(self): """ Process escrow of TEL events received before the anchoring KEL event. @@ -2117,11 +2118,9 @@ def processEscrowAnchorless(self): traw = self.reger.getTvt(dgkey) if traw is None: # no event so raise ValidationError which unescrows below - logger.info("Tevery unescrow error: Missing event at." - "dig = %s\n", bytes(digb)) - - raise ValidationError("Missing escrowed evt at dig = {}." - "".format(bytes(digb))) + msg = f"Tevery: anchorless escrow unescrow error: Missing event at dig = {bytes(digb)}" + logger.trace(msg) + raise ValidationError(msg) tserder = serdering.SerderKERI(raw=bytes(traw)) # escrowed event @@ -2131,11 +2130,9 @@ def processEscrowAnchorless(self): couple = self.reger.getAnc(dgkey) if couple is None: - logger.info("Tevery unescrow error: Missing anchor at." - "dig = %s\n", bytes(digb)) - - raise MissingAnchorError("Missing escrowed anchor at dig = {}." - "".format(bytes(digb))) + msg = f"Tevery: anchorless escrow unescrow error: Missing anchor at dig = {bytes(digb)}" + logger.trace(msg) + raise MissingAnchorError(msg) ancb = bytearray(couple) seqner = coring.Seqner(qb64b=ancb, strip=True) saider = coring.Saider(qb64b=ancb, strip=True) @@ -2144,23 +2141,22 @@ def processEscrowAnchorless(self): except MissingAnchorError as ex: # still waiting on missing prior event to validate - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Tevery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Tevery unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Tevery: anchorless escrow unescrow failed: %s\n", ex.args[0]) + logger.exception("Tevery: anchorless escrow unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow self.reger.delTae(snKey(pre, sn)) # removes one escrow at key val if logger.isEnabledFor(logging.DEBUG): - logger.exception("Tevery unescrowed: %s\n", ex.args[0]) + logger.exception("Tevery: anchorless escrow other error on unescrow: %s\n", ex.args[0]) else: - logger.error("Tevery unescrowed: %s\n", ex.args[0]) + logger.error("Tevery: anchorless escrow other error on unescrow: %s\n", ex.args[0]) else: # unescrow succeeded, remove from escrow # We don't remove all escrows at pre,sn because some might be # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.reger.delTae(snKey(pre, sn)) # removes from escrow - logger.info("Tevery unescrow succeeded in valid event: " - "event=\n%s\n", json.dumps(tserder.ked, indent=1)) + logger.info("Tevery: anchorless escrow unescrow succeeded in valid event: " + "event=\n%s\n", tserder.pretty()) diff --git a/src/keri/vdr/verifying.py b/src/keri/vdr/verifying.py index d7fcb245b..39e4e052f 100644 --- a/src/keri/vdr/verifying.py +++ b/src/keri/vdr/verifying.py @@ -263,10 +263,9 @@ def _processEscrow(self, db, timeout, etype: Type[Exception]): self.processCredential(creder, prefixer, seqner, saider) except etype as ex: - if logger.isEnabledFor(logging.DEBUG): - logger.exception("Verifiery unescrow failed: %s\n", ex.args[0]) - else: - logger.error("Verifier unescrow failed: %s\n", ex.args[0]) + if logger.isEnabledFor(logging.TRACE): + logger.trace("Verifier unescrow failed: %s\n", ex.args[0]) + logger.exception("Verifier unescrow failed: %s\n", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than missing sigs so remove from PA escrow db.rem(said) From 8b0ca13b000188fba23228faeabb0158c476b4b1 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 2 Jan 2025 08:46:36 -0500 Subject: [PATCH 48/61] version 1.1.28 Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 76f20b95f..7b2a0f871 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.27 +VERSION=1.1.28 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 52fae4386..f13282105 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.27` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.28` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 3a70c5fec..3f0b37727 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.27', # also change in src/keri/__init__.py + version='1.1.28', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 52782836c..ddf5cd55c 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.27' # also change in setup.py +__version__ = '1.1.28' # also change in setup.py From 2627a8192a539fff3c34c6e78e44001ae4f684b0 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Thu, 2 Jan 2025 09:04:12 -0500 Subject: [PATCH 49/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 7b2a0f871..f13098ed7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.28 +VERSION=1.1.29 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index f13282105..d5ea6275e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.28` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.29` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 3f0b37727..83f845981 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.28', # also change in src/keri/__init__.py + version='1.1.29', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index ddf5cd55c..b37ef533b 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.28' # also change in setup.py +__version__ = '1.1.29' # also change in setup.py From 62ff39a2336639166a43697ebfb2a9bb07bb1590 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Mon, 13 Jan 2025 07:25:04 -0700 Subject: [PATCH 50/61] fix: add missing private arg to proving.credential() (#925) --- src/keri/vdr/credentialing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index fd97b8f9e..c249736c3 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -805,6 +805,7 @@ def create(self, regname, recp: str, schema, source, rules, data, private: bool recipient=recp, data=data, source=source, + private=private, private_credential_nonce=private_credential_nonce, private_subject_nonce=private_subject_nonce, rules=rules, From daf9cda7b075e8b2f783ebb0568832b73cd30252 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 13 Jan 2025 10:46:24 -0500 Subject: [PATCH 51/61] 1.1.30 Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f13098ed7..c94b8ceb7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.29 +VERSION=1.1.30 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index d5ea6275e..6899284bf 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.29` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.30` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 83f845981..e4311c0e2 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.29', # also change in src/keri/__init__.py + version='1.1.30', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index b37ef533b..0dcc8ce65 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.29' # also change in setup.py +__version__ = '1.1.30' # also change in setup.py From 100b16257407a901535b288f380438dbedb3271b Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Fri, 21 Feb 2025 15:29:05 -0700 Subject: [PATCH 52/61] to 1.1.30: feat: add consistent logging at INFO and DEBUG levels (#930) * feat: add consistent logging at INFO and DEBUG levels The goal is to make viewing the logs at the INFO level nice when manually reviewing log output and to make the DEBUG output comprehensive for everything except escrow logging. * feat: add rich logging format string * fix: verbose logging in Sally tuned down * refactor: remove class name prefixes --- src/keri/app/cli/commands/multisig/incept.py | 2 +- src/keri/app/cli/commands/witness/demo.py | 13 +++- src/keri/app/grouping.py | 19 ++--- src/keri/core/eventing.py | 28 ++++--- src/keri/core/parsing.py | 80 +++++++++++++------- src/keri/core/routing.py | 11 +-- src/keri/db/escrowing.py | 18 ++--- src/keri/peer/exchanging.py | 28 ++++--- src/keri/vdr/credentialing.py | 3 +- src/keri/vdr/eventing.py | 14 ++-- src/keri/vdr/verifying.py | 3 +- 11 files changed, 137 insertions(+), 82 deletions(-) diff --git a/src/keri/app/cli/commands/multisig/incept.py b/src/keri/app/cli/commands/multisig/incept.py index 1c589ab53..605a91040 100644 --- a/src/keri/app/cli/commands/multisig/incept.py +++ b/src/keri/app/cli/commands/multisig/incept.py @@ -156,7 +156,7 @@ def inceptDo(self, tymth, tock=0.0): serder=exn, attachment=ims) - print(f"Group identifier inception initialized for {ghab.pre}") + logger.info(f"Group identifier inception initialized for {ghab.pre}") prefixer = coring.Prefixer(qb64=ghab.pre) seqner = coring.Seqner(sn=0) saider = coring.Saider(qb64=prefixer.qb64) diff --git a/src/keri/app/cli/commands/witness/demo.py b/src/keri/app/cli/commands/witness/demo.py index dd83dc849..8a9a27a31 100644 --- a/src/keri/app/cli/commands/witness/demo.py +++ b/src/keri/app/cli/commands/witness/demo.py @@ -8,6 +8,7 @@ import argparse import logging +import os from hio.base import doing @@ -16,18 +17,26 @@ from keri import help parser = argparse.ArgumentParser(description="Run a demo collection of witnesses") +parser.add_argument("--loglevel", action="store", required=False, default=os.getenv("KERI_LOG_LEVEL", "CRITICAL"), + help="Set log level to DEBUG | INFO | WARNING | ERROR | CRITICAL. Default is CRITICAL") parser.set_defaults(handler=lambda args: demo(args)) -help.ogler.level = logging.INFO logger = help.ogler.getLogger() -def demo(_): +def demo(args): """ Run set of three witnesses for demo """ + base_formatter = logging.Formatter( + '%(asctime)s [keri] %(module)s.%(funcName)s-%(lineno)s %(levelname)-8s %(message)s') + base_formatter.default_msec_format = None + help.ogler.baseConsoleHandler.setFormatter(base_formatter) + help.ogler.level = logging.getLevelName(args.loglevel.upper()) + logger.setLevel(help.ogler.level) + help.ogler.reopen(name="keri", temp=True, clear=True) wancf = configing.Configer(name="wan", headDirPath="scripts", temp=False, reopen=True, clear=False) wilcf = configing.Configer(name="wil", headDirPath="scripts", temp=False, reopen=True, clear=False) diff --git a/src/keri/app/grouping.py b/src/keri/app/grouping.py index 1607ee29f..51f58ce0a 100644 --- a/src/keri/app/grouping.py +++ b/src/keri/app/grouping.py @@ -51,7 +51,7 @@ def start(self, ghab, prefixer, seqner, saider): serder = serdering.SerderKERI(raw=evt) del evt[:serder.size] - print(f"Waiting for other signatures for {serder.pre}:{seqner.sn}...") + logger.info(f"Waiting for other signatures for {serder.ilk} {serder.pre}:{seqner.sn}...") return self.hby.db.gpse.add(keys=(prefixer.qb64,), val=(seqner, saider)) def complete(self, prefixer, seqner, saider=None): @@ -133,7 +133,7 @@ def processPartialSignedEscrow(self): if kever.delegated and kever.ilk in (coring.Ilks.dip, coring.Ilks.drt): # We are a delegated identifier, must wait for delegator approval for dip and drt if witered: # We are elected to perform delegation and witnessing messaging - print(f"We are the witnesser, sending {pre} to delegator") + logger.info(f"We are the witnesser, sending {pre} to delegator") self.swain.delegation(pre=pre, sn=seqner.sn) else: anchor = dict(i=pre, s=seqner.snh, d=saider.qb64) @@ -142,15 +142,15 @@ def processPartialSignedEscrow(self): else: self.witq.query(src=ghab.mhab.pre, pre=kever.delegator, anchor=anchor) - print("Waiting for delegation approval...") + logger.info(f"Waiting for delegation approval...") self.hby.db.gdee.add(keys=(pre,), val=(seqner, saider)) else: # Non-delegation, move on to witnessing if witered: # We are elected witnesser, send off event to witnesses - print(f"We are the fully signed witnesser {seqner.sn}, sending to witnesses") + logger.info(f"We are the fully signed witnesser {seqner.sn}, sending to witnesses") self.witDoer.msgs.append(dict(pre=pre, sn=seqner.sn)) # Move to escrow waiting for witness receipts - print(f"Waiting for fully signed witness receipts for {seqner.sn}") + logger.info(f"Waiting for fully signed witness receipts for {seqner.sn}") self.hby.db.gpwe.add(keys=(pre,), val=(seqner, saider)) def processDelegateEscrow(self): @@ -170,7 +170,7 @@ def processDelegateEscrow(self): if witer: # We are elected witnesser, We've already done out part in Boatswain, we are done. if self.swain.complete(prefixer=kever.prefixer, seqner=coring.Seqner(sn=kever.sn)): self.hby.db.gdee.rem(keys=(pre,)) - print(f"Delegation approval for {pre} received.") + logger.info(f"Delegation approval for {pre} received.") self.hby.db.cgms.put(keys=(pre, seqner.qb64), val=saider) @@ -181,10 +181,10 @@ def processDelegateEscrow(self): dgkey = dbing.dgKey(pre, saider.qb64b) self.hby.db.setAes(dgkey, couple) # authorizer event seal (delegator/issuer) self.hby.db.gdee.rem(keys=(pre,)) - print(f"Delegation approval for {pre} received.") + logger.info(f"Delegation approval for {pre} received.") # Move to escrow waiting for witness receipts - print(f"Waiting for witness receipts for {pre}") + logger.info(f"Waiting for witness receipts for {pre}") self.hby.db.gdee.rem(keys=(pre,)) self.hby.db.gpwe.add(keys=(pre,), val=(seqner, saider)) @@ -212,7 +212,7 @@ def processPartialWitnessEscrow(self): witnessed = True if not witnessed: continue - print(f"Witness receipts complete, {pre} confirmed.") + logger.info(f"Witness receipts complete, {pre} confirmed.") self.hby.db.gpwe.rem(keys=(pre,)) self.hby.db.cgms.put(keys=(pre, seqner.qb64), val=saider) elif not witer: @@ -243,6 +243,7 @@ def handle(self, serder, attachments=None): attachments (list): list of tuples of pather, CESR SAD path attachments to the exn event """ + logger.info("handling %s event SAID=%s", self.resource, serder.said) self.mux.add(serder=serder) diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index 591fa9acd..5bbe5f2ca 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -2294,7 +2294,7 @@ def valSigsDelWigs(self, serder, sigers, verfers, tholder, if delseqner and delsaider: self.escrowPACouple(serder=serder, seqner=delseqner, saider=delsaider) msg=(f"Failure satisfying sith = {tholder.sith} " - f"on sigs {[siger.qb64 for siger in sigers]}" + f"on sigs {[siger.qb64 for siger in sigers]} " f"for evt = {serder.said}") logger.trace(msg) logger.trace("Event Body=\n%s\n", serder.pretty()) @@ -2496,8 +2496,9 @@ def validateDelegation(self, serder, sigers, wigers=None, delseqner=None, delsai # during initial delegation we just escrow the delcept event if delseqner is None and delsaider is None and delegator is not None: self.escrowPSEvent(serder=serder, sigers=sigers, wigers=wigers) - raise MissingDelegationError("No delegation seal for delegator {} " - "with evt = {}.".format(delegator, serder.ked)) + msg = (f"No delegation seal for delegator {delegator} with event = {serder.said}") + logger.debug("Event Body=\n%s\n", serder.pretty()) + raise MissingDelegationError(msg) ssn = validateSN(sn=delseqner.snh, inceptive=False) # delseqner Number should already do this #ssn = sner.num sner is Number seqner is Seqner need to replace Seqners with Numbers @@ -2702,7 +2703,7 @@ def logEvent(self, serder, sigers=None, wigers=None, wits=None, first=False, if self.cues is not None: # cue to notice BadCloneFN self.cues.push(dict(kin="noticeBadCloneFN", serder=serder, fn=fn, firner=firner, dater=dater)) - logger.info("Kever: Mismatch Cloned Replay FN: First seen " + logger.info("Mismatch Cloned Replay FN: First seen " "ordinal fn %s dig %s and clone fn %s event=%s", fn, serder.pre, firner.sn, serder.said) logger.debug("Event Body=\n%s\n", serder.pretty()) @@ -2710,12 +2711,14 @@ def logEvent(self, serder, sigers=None, wigers=None, wits=None, first=False, dtsb = dater.dtsb self.db.setDts(dgkey, dtsb) # first seen so set dts to now self.db.fons.pin(keys=dgkey, val=Seqner(sn=fn)) - logger.info("Kever: First seen ordinal %s dig: %s at %s", - fn, serder.pre, dtsb.decode()) + logger.debug("Kever: First seen %s %s SAID=%s for %s at %s", + fn, serder.ilk, serder.said, serder.pre, dtsb.decode("utf-8")) logger.debug("Event Body=\n%s\n", serder.pretty()) self.db.addKe(snKey(serder.preb, serder.sn), serder.saidb) - logger.info("Kever: Added to KEL valid %s event %s for AID %s", serder.ilk, serder.said, serder.pre) - logger.debug("KEL Event Body=\n%s\n", serder.pretty()) + pre = self.prefixer.qb64 + logger.info("[AID %s...%s]: Added to KEL %s at sn=%s valid event SAID=%s for AID %s", + pre[:4], pre[-4:], serder.ilk, serder.sn, serder.said, serder.pre) + logger.debug("Event Body=\n%s\n", serder.pretty()) return (fn, dtsb.decode("utf-8")) # (fn int, dts str) if first else (None, dts str) def escrowPSEvent(self, serder, sigers, wigers=None): @@ -2736,7 +2739,7 @@ def escrowPSEvent(self, serder, sigers, wigers=None): self.db.putEvt(dgkey, serder.raw) snkey = snKey(serder.preb, serder.sn) self.db.addPse(snkey, serder.saidb) # b'EOWwyMU3XA7RtWdelFt-6waurOTH_aW_Z9VTaU-CshGk.00000000000000000000000000000001' - logger.info("Kever: Escrowed partially signed or delegated " + logger.debug("Kever: Escrowed partially signed or delegated " "event %s for AID %s", serder.said, serder.pre) logger.debug("Event Body=\n%s\n", serder.pretty()) @@ -5037,7 +5040,7 @@ def processEscrowUnverWitness(self): # valid event escrow. self.db.delUwe(snKey(pre, sn), ecouple) # removes one escrow at key val logger.info("Kevery: unver wit escrow unescrow succeeded for event pre=%s " - "sn=%s\n", pre, sn) + "sn=%s", pre, sn) if ekey == key: # still same so no escrows found on last while iteration break @@ -5200,7 +5203,7 @@ def processEscrowUnverNonTrans(self): # valid event escrow. self.db.delUre(snKey(pre, sn), etriplet) # removes one escrow at key val logger.info("Kevery: unver nontrans escrow unescrow succeeded for event pre=%s " - "sn=%s\n", pre, sn) + "sn=%s", pre, sn) if ekey == key: # still same so no escrows found on last while iteration break @@ -5578,7 +5581,8 @@ def processEscrowUnverTrans(self): # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.db.delVre(snKey(pre, sn), equinlet) # removes one escrow at key val - logger.info("Kevery: unver trans escrow unescrow succeeded for event = %s\n", serder.ked) + logger.info("Kevery: unver trans escrow unescrow succeeded for event = %s", serder.said) + logger.debug("Event Body= \n%s\n", serder.pretty()) if ekey == key: # still same so no escrows found on last while iteration break diff --git a/src/keri/core/parsing.py b/src/keri/core/parsing.py index 2b4798dbe..145bbec46 100644 --- a/src/keri/core/parsing.py +++ b/src/keri/core/parsing.py @@ -1041,7 +1041,7 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, elif ilk in [Ilks.rct]: # event receipt msg (nontransferable) if not (cigars or wigers or tsgs): - logger.debug("Parser: Missing attached signatures on receipt msg = %s.", serder.ked) + logger.debug("Parser: Missing attached signatures on receipt msg event =\n%s\n", serder.pretty()) raise kering.ValidationError(f"Missing attached sigs on receipt msg={serder.ked['d']}") try: @@ -1055,13 +1055,17 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, kvy.processReceiptTrans(serder=serder, tsgs=tsgs) except AttributeError: - raise kering.ValidationError("No kevery to process so dropped msg" - "= {}.".format(serder.pretty())) + msg = f"No kevery to process so dropped msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) elif ilk in (Ilks.rpy,): # reply message if not (cigars or tsgs): - raise kering.ValidationError("Missing attached endorser signature(s) " - "to reply msg = {}.".format(serder.pretty())) + msg = f"Missing attached endorser signature(s) to reply msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) try: if cigars: # process separately so do not clash on errors @@ -1071,8 +1075,10 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, rvy.processReply(serder, tsgs=tsgs) # trans except AttributeError as e: - raise kering.ValidationError("No kevery to process so dropped msg" - "= {}.".format(serder.pretty())) + msg = f"No kevery to process so dropped msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) except kering.UnverifiedReplyError as e: if logger.isEnabledFor(logging.DEBUG): logger.exception("Error processing reply = %s", e) @@ -1091,16 +1097,20 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, args["cigars"] = cigars else: - raise kering.ValidationError("Missing attached requester signature(s) " - "to key log query msg = {}.".format(serder.pretty())) + msg = f"Missing attached requester signature(s) to key log query msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) route = serder.ked["r"] if route in ["logs", "ksn", "mbx"]: try: kvy.processQuery(**args) except AttributeError: - raise kering.ValidationError("No kevery to process so dropped msg" - "= {}.".format(serder.pretty())) + msg = f"No kevery to process so dropped msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) except kering.QueryNotFoundError as e: # catch escrow error and log it if logger.isEnabledFor(logging.TRACE): logger.exception("Error processing query = %s", e) @@ -1112,12 +1122,16 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, try: tvy.processQuery(**args) except AttributeError as e: - raise kering.ValidationError("No tevery to process so dropped msg" - "= {} from {}.".format(serder.pretty(), e)) + msg = f"No tevery to process so dropped msg = {serder.said} from {e}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) else: - raise kering.ValidationError("Invalid resource type {} so dropped msg" - "= {}.".format(route, serder.pretty())) + msg = f"Invalid resource type {route} so dropped msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) elif ilk in (Ilks.exn,): args = dict(serder=serder) @@ -1132,8 +1146,10 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, exc.processEvent(tsgs=tsgs, **args) except AttributeError: - raise kering.ValidationError("No Exchange to process so dropped msg" - "= {}.".format(serder.pretty())) + msg = "No Exchange to process so dropped msg = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) elif ilk in (Ilks.vcp, Ilks.vrt, Ilks.iss, Ilks.rev, Ilks.bis, Ilks.brv): # TEL msg @@ -1143,11 +1159,15 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, tvy.processEvent(serder=serder, seqner=seqner, saider=saider, wigers=wigers) except AttributeError as e: - raise kering.ValidationError("No tevery to process so dropped msg" - "= {}.".format(serder.pretty())) + msg = f"No Tevery to process so dropped msg = {serder.said}" + logger.debug(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) else: - raise kering.ValidationError("Unexpected message ilk = {} for evt =" - " {}.".format(ilk, serder.pretty())) + msg = f"Unexpected message ilk = {ilk} for evt = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) elif isinstance(serder, serdering.SerderACDC): ilk = serder.ilk # dispatch based on ilk @@ -1157,14 +1177,20 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, prefixer, seqner, saider = ssts[-1] if ssts else (None, None, None) # use last one if more than one vry.processCredential(creder=serder, prefixer=prefixer, seqner=seqner, saider=saider) except AttributeError as e: - raise kering.ValidationError("No verifier to process so dropped credential" - "= {}.".format(serder.pretty())) + msg = f"No verifier to process so dropped credential {serder.said}" + logger.debug(msg) + logger.debug("Credential body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) else: - raise kering.ValidationError("Unexpected message ilk = {} for evt =" - " {}.".format(ilk, serder.pretty())) + msg = f"Unexpected message ilk = {ilk} for evt = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) else: - raise kering.ValidationError("Unexpected protocol type = {} for event message =" - " {}.".format(serder.proto, serder.pretty())) + msg = f"Unexpected protocol type = {serder.proto} for event message = {serder.said}" + logger.info(msg) + logger.debug("Event body=\n%s\n", serder.pretty()) + raise kering.ValidationError(msg) return True # done state diff --git a/src/keri/core/routing.py b/src/keri/core/routing.py index f335b074a..686929684 100644 --- a/src/keri/core/routing.py +++ b/src/keri/core/routing.py @@ -323,9 +323,10 @@ def acceptReply(self, serder, saider, route, aid, osaider=None, if seqner.sn == osqr.sn: # sn same so check datetime if odater: if dater.datetime <= odater.datetime: - logger.info("Kevery process: skipped stale key" - "state sig datetime from %s on reply msg=\n%s\n", - aid, serder.pretty()) + logger.debug("Kevery process: skipped stale key " + "state sig datetime from %s on reply msg = %s", + aid, serder.said) + logger.debug("Reply Body=\n%s\n", serder.pretty()) continue # skip if not later # retrieve sdig of last event at sn of signer. @@ -500,8 +501,8 @@ def processEscrowReply(self): else: # unescrow succeded self.db.rpes.rem(keys=(route, ), val=saider) # remove escrow only - logger.info("Kevery unescrow succeeded for reply=\n%s\n", - serder.pretty()) + logger.info("Kevery unescrow succeeded for reply = %s", serder.said) + logger.debug("Reply Body=\n%s\n", serder.pretty()) except Exception as ex: # log diagnostics errors etc self.db.rpes.rem(keys=(route,), val=saider) # remove escrow only diff --git a/src/keri/db/escrowing.py b/src/keri/db/escrowing.py index ff6fd5268..b903373ea 100644 --- a/src/keri/db/escrowing.py +++ b/src/keri/db/escrowing.py @@ -88,7 +88,7 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): try: if not (dater and serder and (tsgs or vcigars)): - raise ValueError(f"Broker: Missing escrow artifacts at said={saider.qb64}" + raise ValueError(f"Missing escrow artifacts at said={saider.qb64}" f"for pre={pre}.") cigars = [] @@ -101,7 +101,7 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): if ((helping.nowUTC() - dater.datetime) > datetime.timedelta(seconds=self.timeout)): # escrow stale so raise ValidationError which unescrows below - msg = f"Broker: {typ} escrow unescrow error: Stale txn state escrow at pre = {pre}" + msg = f"{typ} escrow unescrow error: Stale txn state escrow at pre = {pre}" logger.trace(msg) raise kering.ValidationError(msg) @@ -111,19 +111,19 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): except extype as ex: # still waiting on missing prior event to validate if logger.isEnabledFor(logging.TRACE): - logger.trace("Broker: %s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) - logger.exception("Broker: %s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) + logger.trace("%s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) + logger.exception("%s escrow unescrow attempt failed: %s\n", typ, ex.args[0]) except Exception as ex: # other error so remove from reply escrow self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow if logger.isEnabledFor(logging.DEBUG): - logger.exception("Broker: %s escrow other error on unescrow: %s\n", typ, ex.args[0]) + logger.exception("%s escrow other error on unescrow: %s\n", typ, ex.args[0]) else: - logger.error("Broker: %s escrow other error on unescrow: %s\n", typ, ex.args[0]) + logger.error("%s escrow other error on unescrow: %s\n", typ, ex.args[0]) else: # unescrow succeded self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow only - logger.info("Broker: %s escrow unescrow succeeded for txn state=%s", + logger.info("%s escrow unescrow succeeded for txn state = %s", typ, serder.said) logger.debug("TXN State Body=\n%s\n", serder.pretty()) @@ -131,9 +131,9 @@ def processEscrowState(self, typ, processReply, extype: Type[Exception]): self.escrowdb.remIokey(iokeys=(typ, pre, aid, ion)) # remove escrow self.removeState(saider) if logger.isEnabledFor(logging.DEBUG): - logger.exception("Broker: %s escrow unescrowed due to error: %s\n", typ, ex.args[0]) + logger.exception("%s escrow unescrowed due to error: %s\n", typ, ex.args[0]) else: - logger.error("Broker: %s escrow unescrowed due to error: %s\n", typ, ex.args[0]) + logger.error("%s escrow unescrowed due to error: %s\n", typ, ex.args[0]) def escrowStateNotice(self, *, typ, pre, aid, serder, saider, dater, cigars=None, tsgs=None): """ diff --git a/src/keri/peer/exchanging.py b/src/keri/peer/exchanging.py index 1b100d66d..5302efd22 100644 --- a/src/keri/peer/exchanging.py +++ b/src/keri/peer/exchanging.py @@ -92,8 +92,10 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): if not tholder.satisfy(indices): # We still don't have all the sigers, need to escrow if self.escrowPSEvent(serder=serder, tsgs=tsgs, pathed=pathed): self.cues.append(dict(kin="query", q=dict(r="logs", pre=prefixer.qb64, sn=seqner.snh))) - raise MissingSignatureError(f"Not enough signatures in {indices}" - f" for evt = {serder.ked}.") + msg = f"Not enough signatures in {indices} for evt = {serder.said}" + logger.info(msg) + logger.debug(f"Event body=\n%20\n", serder.pretty()) + raise MissingSignatureError(msg) elif cigars is not None: for cigar in cigars: @@ -136,7 +138,7 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): try: behavior.handle(serder=serder, attachments=attachments) except AttributeError: - logger.info(f"Behavior for {route} missing or does not have handle for exn={serder.said}") + logger.debug(f"Behavior for {route} missing or does not have handle for exn={serder.said}") logger.debug( f"exn body=\n{serder.ked}\n") @@ -193,18 +195,18 @@ def processEscrowPartialSigned(self): except MissingSignatureError as ex: logger.trace("Exchange partially signed unescrow failed: %s\n", ex.args[0]) if logger.isEnabledFor(logging.TRACE): - logger.debug(f"Event body=\n{serder.pretty()}\n") + logger.debug("Event body=\n%s\n", serder.pretty()) except Exception as ex: self.hby.db.epse.rem(dig) self.hby.db.esigs.rem(dig) logger.info("Exchange partially signed unescrowed: %s\n", ex.args[0]) if logger.isEnabledFor(logging.DEBUG): - logger.debug(f"Event body=\n{serder.pretty()}\n") + logger.debug("Event body=\n%s\n", serder.pretty()) else: self.hby.db.epse.rem(dig) self.hby.db.esigs.rem(dig) - logger.info(f"Exchanger unescrow succeeded in valid exchange: serder={serder.said}") - logger.debug(f"Serder Body=\n{serder.pretty()}\n") + logger.info("Exchanger unescrow succeeded in valid exchange: serder = %s", serder.said) + logger.debug("Serder Body=\n%s\n", serder.pretty()) def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): dig = serder.said @@ -226,6 +228,12 @@ def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): self.hby.db.erpy.pin(keys=(pdig,), val=saider) self.hby.db.exns.put(keys=(dig,), val=serder) + recipient = serder.ked['rp'] + sender = serder.ked['i'] + route = serder.ked['r'] + logger.info("Saved exn event route = %s SAID = %s sender %s -> recipient %s", + route, dig, sender, recipient) + logger.debug("EXN Event Body=\n%s\n", serder.pretty()) def lead(self, hab, said): """ Determines is current member represented by hab is the lead of an exn message @@ -480,8 +488,10 @@ def verify(hby, serder): _, indices = eventing.verifySigs(serder.raw, sigers, verfers) if not tholder.satisfy(indices): # We still don't have all the sigers, need to escrow - raise MissingSignatureError(f"Not enough signatures in {indices}" - f" for evt = {serder.ked}.") + msg = f"Not enough signatures in {indices} for evt = {serder.said}" + logger.info("exchanging.verify: %s", msg) + logger.debug(f"Event body=\n%s\n", serder.pretty()) + raise MissingSignatureError(msg) accepted = True cigars = hby.db.ecigs.get(keys=(serder.said,)) diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index c249736c3..d3ba18c0c 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -234,7 +234,8 @@ def processEvent(self, serder): try: self.tvy.processEvent(serder=serder) except kering.MissingAnchorError: - logger.info("Credential registry missing anchor for inception = {}".format(serder.ked)) + logger.info("Credential registry missing anchor for inception = {}".format(serder.said)) + logger.debug("Inception body = {}".format(serder.pretty())) def anchorMsg(self, pre, regd, seqner, saider): """ Create key event with seal to serder anchored as data. diff --git a/src/keri/vdr/eventing.py b/src/keri/vdr/eventing.py index 030ce18be..bedfe98f7 100644 --- a/src/keri/vdr/eventing.py +++ b/src/keri/vdr/eventing.py @@ -1267,7 +1267,8 @@ def logEvent(self, pre, sn, serder, seqner, saider, bigers=None, baks=None): self.reger.tets.pin(keys=(pre.decode("utf-8"), dig.decode("utf-8")), val=coring.Dater()) self.reger.putTvt(key, serder.raw) self.reger.putTel(snKey(pre, sn), dig) - logger.info("Tever: Added to TEL valid %s event=%s for AID %s", serder.ilk, serder.said, serder.pre) + logger.info("Tever: Added to TEL %s valid event=%s SAID=%s reg=%.8s... iss=%s", + serder.ilk, serder.pre, serder.said, self.regk, self.pre) logger.debug("TEL Event Body=\n%s\n", serder.pretty()) def valAnchorBigs(self, serder, seqner, saider, bigers, toad, baks): @@ -1423,8 +1424,8 @@ def escrowALEvent(self, serder, seqner, saider, bigers=None, baks=None): self.reger.delBaks(key) self.reger.putBaks(key, [bak.encode("utf-8") for bak in baks]) self.reger.putTvt(key, serder.raw) - logger.info("Tever state: Escrowed anchorless event " - "event = %s\n", serder.ked) + logger.info("Tever: Escrowed anchorless event event = %s", serder.said) + logger.debug("Event body=\n%s\n", serder.ked) return self.reger.putTae(snKey(serder.preb, serder.sn), serder.saidb) def getBackerState(self, ked): @@ -2096,8 +2097,8 @@ def processEscrowOutOfOrders(self): # duplicitous so we process remaining escrows in spite of found # valid event escrow. self.reger.delOot(snKey(pre, sn)) # removes from escrow - logger.info("Tevery unescrow succeeded in valid event: " - "event=\n%s\n", tserder.pretty()) + logger.info("Tevery unescrow succeeded in valid event: event = %s", tserder.said) + logger.debug("Event Body=\n%s\n", tserder.pretty()) def processEscrowAnchorless(self): """ Process escrow of TEL events received before the anchoring KEL event. @@ -2159,4 +2160,5 @@ def processEscrowAnchorless(self): # valid event escrow. self.reger.delTae(snKey(pre, sn)) # removes from escrow logger.info("Tevery: anchorless escrow unescrow succeeded in valid event: " - "event=\n%s\n", tserder.pretty()) + "event = %s", tserder.said) + logger.debug("Event body=\n%s\n", tserder.pretty()) diff --git a/src/keri/vdr/verifying.py b/src/keri/vdr/verifying.py index 39e4e052f..4ebf9b420 100644 --- a/src/keri/vdr/verifying.py +++ b/src/keri/vdr/verifying.py @@ -276,7 +276,8 @@ def _processEscrow(self, db, timeout, etype: Type[Exception]): else: db.rem(said) logger.info("Verifier unescrow succeeded in valid group op: " - "creder=\n%s\n", creder.pretty()) + "creder = %s", creder.said) + logger.debug("Creder body=\n%s\n", creder.pretty()) def saveCredential(self, creder, prefixer, seqner, saider): """ Write the credential and associated indicies to the database From bb2b9ddf082b3e6237f737b790e60468ea6e23f5 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Sun, 23 Feb 2025 19:59:08 -0500 Subject: [PATCH 53/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c94b8ceb7..578382f61 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.30 +VERSION=1.1.31 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 6899284bf..8e8522691 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.30` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.31` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index e4311c0e2..c374e1b0e 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.30', # also change in src/keri/__init__.py + version='1.1.31', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 0dcc8ce65..e7383c9ec 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.30' # also change in setup.py +__version__ = '1.1.31' # also change in setup.py From 620d172d46f7fc62dddcf34a11bbdf0a8f3c1a6e Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 24 Feb 2025 10:18:23 -0500 Subject: [PATCH 54/61] list Signed-off-by: Kevin Griffin --- src/keri/app/cli/commands/mailbox/list.py | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/keri/app/cli/commands/mailbox/list.py diff --git a/src/keri/app/cli/commands/mailbox/list.py b/src/keri/app/cli/commands/mailbox/list.py new file mode 100644 index 000000000..369e749df --- /dev/null +++ b/src/keri/app/cli/commands/mailbox/list.py @@ -0,0 +1,68 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse + +from hio import help +from hio.base import doing + +from keri.app import connecting +from keri.app.cli.common import existing +from keri.kering import ConfigurationError, Roles + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='List current mailboxes') +parser.set_defaults(handler=lambda args: handle(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--alias', '-a', help='human readable alias for the identifier to whom the credential was issued', + required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran + + +def handle(args): + """ Command line handler for adding an aid to a watcher's list of AIds to watch + + Parameters: + args(Namespace): parsed command line arguments + + """ + + kwa = dict(args=args) + return [doing.doify(listMailboxes, **kwa)] + + +def listMailboxes(tymth, tock=0.0, **opts): + """ Command line status handler + + """ + _ = (yield tock) + args = opts["args"] + name = args.name + alias = args.alias + base = args.base + bran = args.bran + + try: + with existing.existingHby(name=name, base=base, bran=bran) as hby: + org = connecting.Organizer(hby=hby) + if alias is None: + alias = existing.aliasInput(hby) + + hab = hby.habByName(alias) + + for (aid, role, eid), ender in hab.db.ends.getItemIter(keys=(hab.pre, Roles.mailbox)): + if ender.allowed: + contact = org.get(eid) + print(f"{contact['alias']}: {eid}") + + except ConfigurationError as e: + print(f"identifier prefix for {name} does not exist, incept must be run first", ) + return -1 From a06fae1478887a50f30d1c0792cc83495d4a7f3b Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Tue, 25 Feb 2025 13:18:35 -0500 Subject: [PATCH 55/61] cleans up escrow counts Signed-off-by: Kevin Griffin --- src/keri/db/basing.py | 5 ++--- src/keri/db/subing.py | 14 ++++++++++++++ tests/db/test_basing.py | 28 ++++++++++++++-------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index eddb93047..48a0c074a 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1222,11 +1222,10 @@ def clearEscrows(self): ('gpse', self.gpse, 'group partial signature escrow'), ('epse', self.epse, 'exchange partial signature escrow'), ('dune', self.dune, 'delegated unanchored escrow')]: - count = 0 - for (k, _) in escrow.getItemIter(): - count += 1 + count = escrow.cntAll() escrow.trim() logger.info(f"KEL: Cleared {count} escrows from ({name.ljust(5)}): {desc}") + logger.info("Cleared KEL escrows") @property diff --git a/src/keri/db/subing.py b/src/keri/db/subing.py index 754cc553a..76422692c 100644 --- a/src/keri/db/subing.py +++ b/src/keri/db/subing.py @@ -187,6 +187,20 @@ def trim(self, keys: Union[str, Iterable]=b""): """ return(self.db.delTopVal(db=self.sdb, key=self._tokey(keys))) + def cntAll(self): + """ + Return iterator over the all the items in subdb + + Returns: + iterator: of tuples of keys tuple and val dataclass instance for + each entry in db. Raises StopIteration when done + + Example: + if key in database is "a.b" and val is serialization of dataclass + with attributes x and y then returns + (("a","b"), dataclass(x=1,y=2)) + """ + return self.db.cnt(db=self.sdb) class Suber(SuberBase): """ diff --git a/tests/db/test_basing.py b/tests/db/test_basing.py index df04d7345..d506d9439 100644 --- a/tests/db/test_basing.py +++ b/tests/db/test_basing.py @@ -2301,29 +2301,29 @@ def test_clear_escrows(): pre = 'k' saider = coring.Saider(qb64b='EGAPkzNZMtX-QiVgbRbyAIZGoXvbGv9IPb0foWTZvI_4') db.rpes.put(keys=('route',), vals=[saider]) - assert db.rpes.cnt(keys=('route',)) == 1 + assert db.rpes.cntAll() == 1 db.eoobi.pin(keys=('url',), val=OobiRecord()) assert db.eoobi.cntAll() == 1 db.gpwe.add(keys=(pre,), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) - assert db.gpwe.cnt(keys=(pre,)) == 1 + assert db.gpwe.cntAll() == 1 db.gdee.add(keys=(pre,), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) - assert db.gdee.cnt(keys=(pre,)) == 1 + assert db.gdee.cntAll() == 1 serder = Serder(raw=b'{"v":"KERI10JSON0000cb_","t":"ixn","d":"EG8WAmM29ZBdoXbnb87yiPxQw4Y7gcQjqZS74vBAKsRm","i":"DApYGFaqnrALTyejaJaGAVhNpSCtqyerPqWVK9ZBNZk0","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","a":[]}') db.dpwe.pin(keys=(pre, 'said'), val=serder) - assert db.dpwe.get(keys=(pre, 'said')) is not None + assert db.dpwe.cntAll() == 1 db.gpse.add(keys=('qb64',), val=(coring.Seqner(qb64b=b'0AAAAAAAAAAAAAAAAAAAAAAB'), saider)) - assert db.gpse.cnt(keys=('qb64',)) == 1 + assert db.gpse.cntAll() == 1 db.epse.put(keys=('dig',), val=serder) - assert db.epse.get(keys=('dig',)) is not None + assert db.epse.cntAll() == 1 db.dune.pin(keys=(pre, 'said'), val=serder) - assert db.dune.get(keys=(pre, 'said')) is not None + assert db.dune.cntAll() == 1 db.clearEscrows() @@ -2336,14 +2336,14 @@ def test_clear_escrows(): assert db.getLdes(key) == [] assert db.getQnfs(key) == [] assert db.getPdes(key) == [] - assert db.rpes.cnt(keys=('route',)) == 0 + assert db.rpes.cntAll() == 0 assert db.eoobi.cntAll() == 0 - assert db.gpwe.cnt(keys=(pre,)) == 0 - assert db.gdee.cnt(keys=(pre,)) == 0 - assert db.dpwe.get(keys=(pre, 'said')) is None - assert db.gpse.cnt(keys=('qb64',)) == 0 - assert db.epse.get(keys=('dig',)) is None - assert db.dune.get(keys=(pre, 'said')) is None + assert db.gpwe.cntAll() == 0 + assert db.gdee.cntAll() == 0 + assert db.dpwe.cntAll() == 0 + assert db.gpse.cntAll() == 0 + assert db.epse.cntAll() == 0 + assert db.dune.cntAll() == 0 if __name__ == "__main__": test_baser() From 1657f0eba8b046964a135b83616ce0b629d257cd Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 3 Mar 2025 14:36:30 -0500 Subject: [PATCH 56/61] kli mark, rem, list notifications (#946) * kli mark, rem, list notifications Signed-off-by: Kevin Griffin * clean up makefile Signed-off-by: Kevin Griffin --------- Signed-off-by: Kevin Griffin --- images/keripy.dockerfile | 2 +- .../cli/commands/notifications/__init__.py | 0 .../app/cli/commands/notifications/list.py | 93 ++++++++++++++++ .../app/cli/commands/notifications/mark.py | 101 ++++++++++++++++++ .../app/cli/commands/notifications/rem.py | 101 ++++++++++++++++++ 5 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 src/keri/app/cli/commands/notifications/__init__.py create mode 100644 src/keri/app/cli/commands/notifications/list.py create mode 100644 src/keri/app/cli/commands/notifications/mark.py create mode 100644 src/keri/app/cli/commands/notifications/rem.py diff --git a/images/keripy.dockerfile b/images/keripy.dockerfile index 4e553b87c..71b36b2ec 100644 --- a/images/keripy.dockerfile +++ b/images/keripy.dockerfile @@ -1,6 +1,6 @@ ARG BASE=python:3.12.2-alpine3.19 -FROM ${BASE} as builder +FROM ${BASE} AS builder RUN apk add --no-cache bash diff --git a/src/keri/app/cli/commands/notifications/__init__.py b/src/keri/app/cli/commands/notifications/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/keri/app/cli/commands/notifications/list.py b/src/keri/app/cli/commands/notifications/list.py new file mode 100644 index 000000000..0788ea7c4 --- /dev/null +++ b/src/keri/app/cli/commands/notifications/list.py @@ -0,0 +1,93 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse +import json + +from keri import help +from hio.base import doing + +from keri import kering +from keri.app import agenting, habbing, httping, notifying +from keri.app.cli.common import existing +from keri.app.habbing import GroupHab + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Display notifications for an identifier') +parser.set_defaults(handler=lambda args: handler(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', default=None) +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran +parser.add_argument("--verbose", "-V", help="print JSON of all current events", action="store_true") + + +def handler(args): + """ + List notifications for an identifier. + + Args: + args(Namespace): arguments object from command line + """ + + name = args.name + base = args.base + bran = args.bran + alias = args.alias + verbose = args.verbose + + notesDoer = NotesDoer(name=name, base=base, alias=alias, bran=bran, verbose=verbose) + + doers = [notesDoer] + return doers + + +class NotesDoer(doing.DoDoer): + def __init__(self, name, base, alias, bran, verbose): + + hby = existing.setupHby(name=name, base=base, bran=bran) + self.hbyDoer = habbing.HaberyDoer(habery=hby) # setup doer + self.alias = alias + self.hby = hby + self.verbose = verbose + self.notifier = notifying.Notifier(hby=self.hby) + + doers = [self.hbyDoer, doing.doify(self.readDo)] + + super(NotesDoer, self).__init__(doers=doers) + + def readDo(self, tymth, tock=0.0): + """ + Parameters: + tymth (function): injected function wrapper closure returned by .tymen() of + Tymist instance. Calling tymth() returns associated Tymist .tyme. + tock (float): injected initial tock value + + Returns: doifiable Doist compatible generator method + """ + # enter context + self.wind(tymth) + self.tock = tock + _ = (yield self.tock) + + print("Waiting for notifications...") + + while self.notifier.noter.notes.cntAll() == 0: + yield self.tock + + for keys, notice in self.notifier.noter.notes.getItemIter(): + if self.verbose: + print(keys) + print(json.dumps(notice.pad, indent=4)) + else: + print(keys, notice.attrs.get('r', 'no route')) + + self.remove([self.hbyDoer,]) + return diff --git a/src/keri/app/cli/commands/notifications/mark.py b/src/keri/app/cli/commands/notifications/mark.py new file mode 100644 index 000000000..0c70d9d22 --- /dev/null +++ b/src/keri/app/cli/commands/notifications/mark.py @@ -0,0 +1,101 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse + +from keri import help +from hio.base import doing + +from keri import kering +from keri.app import agenting, habbing, httping, notifying +from keri.app.cli.common import existing +from keri.app.habbing import GroupHab + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Display notifications for an identifier') +parser.set_defaults(handler=lambda args: handler(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', default=None) +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran +parser.add_argument("--rid", '-r', help='notification SAID to mark as read', default=None) +parser.add_argument("--all", help="mark all notifications as read", action="store_true") + + +def handler(args): + """ + List notifications for an identifier. + + Args: + args(Namespace): arguments object from command line + """ + + name = args.name + base = args.base + bran = args.bran + alias = args.alias + rid = args.rid + all = args.all + + markDoer = MarkDoer(name=name, base=base, alias=alias, bran=bran, rid=rid, all=all) + + doers = [markDoer] + return doers + + +class MarkDoer(doing.DoDoer): + def __init__(self, name, base, alias, bran, rid, all): + + hby = existing.setupHby(name=name, base=base, bran=bran) + self.hbyDoer = habbing.HaberyDoer(habery=hby) # setup doer + self.alias = alias + self.hby = hby + self.notifier = notifying.Notifier(hby=self.hby) + self.rid = rid + self.all = all + + doers = [self.hbyDoer, doing.doify(self.markDo)] + + super(MarkDoer, self).__init__(doers=doers) + + def markDo(self, tymth, tock=0.0): + """ + Parameters: + tymth (function): injected function wrapper closure returned by .tymen() of + Tymist instance. Calling tymth() returns associated Tymist .tyme. + tock (float): injected initial tock value + + Returns: doifiable Doist compatible generator method + """ + # enter context + self.wind(tymth) + self.tock = tock + _ = (yield self.tock) + + if self.all: + print() + print("This command will mark all notifications as read") + print() + yn = input("Are you sure you want to continue? [y|N]: ") + + if yn not in ("y", "Y"): + print("...exiting") + else: + for n in self.notifier.getNotes(): + print(f"marking {n.rid} as read") + self.notifier.mar(rid=n.rid) + elif self.rid is not None: + print(f"marking {self.rid} as read") + self.notifier.mar(rid=self.rid) + else: + print("Must specify one of --rid or --all") + + self.remove([self.hbyDoer,]) + return diff --git a/src/keri/app/cli/commands/notifications/rem.py b/src/keri/app/cli/commands/notifications/rem.py new file mode 100644 index 000000000..b5f207e99 --- /dev/null +++ b/src/keri/app/cli/commands/notifications/rem.py @@ -0,0 +1,101 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse + +from keri import help +from hio.base import doing + +from keri import kering +from keri.app import agenting, habbing, httping, notifying +from keri.app.cli.common import existing +from keri.app.habbing import GroupHab + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Display notifications for an identifier') +parser.set_defaults(handler=lambda args: handler(args), + transferable=True) +parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True) +parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', + required=False, default="") +parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', default=None) +parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran +parser.add_argument("--rid", '-r', help='notification SAID to mark as read', default=None) +parser.add_argument("--all", help="mark all notifications as read", action="store_true") + + +def handler(args): + """ + List notifications for an identifier. + + Args: + args(Namespace): arguments object from command line + """ + + name = args.name + base = args.base + bran = args.bran + alias = args.alias + rid = args.rid + all = args.all + + removeDoer = RemoveDoer(name=name, base=base, alias=alias, bran=bran, rid=rid, all=all) + + doers = [removeDoer] + return doers + + +class RemoveDoer(doing.DoDoer): + def __init__(self, name, base, alias, bran, rid, all): + + hby = existing.setupHby(name=name, base=base, bran=bran) + self.hbyDoer = habbing.HaberyDoer(habery=hby) # setup doer + self.alias = alias + self.hby = hby + self.notifier = notifying.Notifier(hby=self.hby) + self.rid = rid + self.all = all + + doers = [self.hbyDoer, doing.doify(self.remDoer)] + + super(RemoveDoer, self).__init__(doers=doers) + + def remDoer(self, tymth, tock=0.0): + """ + Parameters: + tymth (function): injected function wrapper closure returned by .tymen() of + Tymist instance. Calling tymth() returns associated Tymist .tyme. + tock (float): injected initial tock value + + Returns: doifiable Doist compatible generator method + """ + # enter context + self.wind(tymth) + self.tock = tock + _ = (yield self.tock) + + if self.all: + print() + print("This command will remove all notifications") + print() + yn = input("Are you sure you want to continue? [y|N]: ") + + if yn not in ("y", "Y"): + print("...exiting") + else: + for n in self.notifier.getNotes(): + print(f"removing {n.rid}") + self.notifier.rem(rid=n.rid) + elif self.rid is not None: + print(f"removing {self.rid}") + self.notifier.rem(rid=self.rid) + else: + print("Must specify one of --rid or --all") + + self.remove([self.hbyDoer,]) + return From 03a3fa34d72e0fb45d752d3c58445ea34bbe9e95 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Mon, 3 Mar 2025 12:39:28 -0700 Subject: [PATCH 57/61] fix: merge instead of replace contact data on re-OOBI (#944) --- src/keri/app/oobiing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keri/app/oobiing.py b/src/keri/app/oobiing.py index 41a5e6c92..3a45c122b 100644 --- a/src/keri/app/oobiing.py +++ b/src/keri/app/oobiing.py @@ -415,7 +415,7 @@ def processClients(self): obr.cid = response["headers"][ending.OOBI_AID_HEADER] if obr.oobialias is not None and obr.cid: - self.org.replace(pre=obr.cid, data=dict(alias=obr.oobialias, oobi=url)) + self.org.update(pre=obr.cid, data=dict(alias=obr.oobialias, oobi=url)) self.hby.db.coobi.rem(keys=(url,)) obr.state = Result.resolved From c14e06763ec95d8c50ab1bc1a97fb553baf343e7 Mon Sep 17 00:00:00 2001 From: Kevin Griffin Date: Mon, 3 Mar 2025 17:06:03 -0500 Subject: [PATCH 58/61] version bump Signed-off-by: Kevin Griffin --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 578382f61..90167aaad 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.31 +VERSION=1.1.32 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index 8e8522691..a37500461 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.31` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.32` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index c374e1b0e..7cca876e0 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.31', # also change in src/keri/__init__.py + version='1.1.32', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index e7383c9ec..10eee9b7f 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.31' # also change in setup.py +__version__ = '1.1.32' # also change in setup.py From 42659ec80a6b28ba887798dd098cccaf8494e8ce Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Wed, 12 Mar 2025 17:55:01 +0530 Subject: [PATCH 59/61] remove unused code --- src/keri/db/dbing.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/keri/db/dbing.py b/src/keri/db/dbing.py index 8f8165e0d..3b5b967b8 100644 --- a/src/keri/db/dbing.py +++ b/src/keri/db/dbing.py @@ -62,8 +62,6 @@ import keri from ..help import helping -logger = help.ogler.getLogger() - ProemSize = 32 # does not include trailing separator MaxProem = int("f"*(ProemSize), 16) MaxON = int("f"*32, 16) # largest possible ordinal number, sequence or first seen @@ -71,8 +69,6 @@ SuffixSize = 32 # does not include trailing separator MaxSuffix = int("f"*(SuffixSize), 16) -KERIDBMapSizeKey = "KERI_DB_MAP_SIZE" - def dgKey(pre, dig): """ Returns bytes DB key from concatenation of '.' with qualified Base64 prefix From 4611f809c35c0dbc60a912aae3b23384befb4be5 Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Thu, 13 Mar 2025 18:53:59 +0530 Subject: [PATCH 60/61] allows missing rp field for exns when it is the only missing field --- Makefile | 2 +- README.md | 2 +- setup.py | 2 +- src/keri/__init__.py | 2 +- src/keri/core/serdering.py | 31 ++++++++++++++++++++++++++----- tests/core/test_serdering.py | 12 ++++++++++++ 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 90167aaad..5a4ad3d5e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build-keri -VERSION=1.1.32 +VERSION=1.1.33 define DOCKER_WARNING In order to use the multi-platform build enable the containerd image store diff --git a/README.md b/README.md index a37500461..b281a2f11 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ to get a version string similar to the following: ### Local installation - Docker build Run `make build-keri` to build your docker image. -Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.32` and you can run `kli version` from within the running container to play with KERIpy. +Then run `docker run --pull=never -it --entrypoint /bin/bash weboftrust/keri:1.1.33` and you can run `kli version` from within the running container to play with KERIpy. Make sure the image tag matches the version used in the `Makefile`. We use `--pull=never` to ensure that docker does not implicitly pull a remote image and relies on the local image tagged during `make build-keri`. diff --git a/setup.py b/setup.py index 7cca876e0..95fd2e053 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ from setuptools import find_packages, setup setup( name='keri', - version='1.1.32', # also change in src/keri/__init__.py + version='1.1.33', # also change in src/keri/__init__.py license='Apache Software License 2.0', description='Key Event Receipt Infrastructure', long_description="KERI Decentralized Key Management Infrastructure", diff --git a/src/keri/__init__.py b/src/keri/__init__.py index 10eee9b7f..55a0b4264 100644 --- a/src/keri/__init__.py +++ b/src/keri/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -__version__ = '1.1.32' # also change in setup.py +__version__ = '1.1.33' # also change in setup.py diff --git a/src/keri/core/serdering.py b/src/keri/core/serdering.py index 2c271a74c..92db8221a 100644 --- a/src/keri/core/serdering.py +++ b/src/keri/core/serdering.py @@ -523,9 +523,19 @@ def _verify(self): del keys[keys.index(key)] # remove non required fields if list(alls.keys()) != keys: # forces ordering of labels in .sad - raise MissingFieldError(f"Missing one or more required fields from" - f"= {list(alls.keys())} in sad = " - f"{self._sad}.") + # special handling for 1.1.18 -> 1.1.32 + skip_missing_field = False + if self.ilk == Ilks.exn: + missing_keys = [key for key in alls.keys() if key not in keys] + if missing_keys: + if len(missing_keys) == 1 and 'rp' in missing_keys: + skip_missing_field = True + if skip_missing_field: + pass + else: + raise MissingFieldError(f"Missing one or more required fields from" + f"= {list(alls.keys())} in sad = " + f"{self._sad}.") # said field labels are not order dependent with respect to all fields # in sad so use set() to test inclusion @@ -1105,8 +1115,19 @@ def _verify(self, **kwa): allkeys = list(self.Fields[self.proto][self.vrsn][self.ilk].alls.keys()) keys = list(self.sad.keys()) if allkeys != keys: - raise ValidationError(f"Invalid top level field list. Expected " - f"{allkeys} got {keys}.") + # special handling for 1.1.18 -> 1.1.32 + skip_missing_field = False + if self.ilk == Ilks.exn: + missing_keys = [key for key in allkeys if key not in keys] + if missing_keys: + if len(missing_keys) == 1 and 'rp' in missing_keys: + skip_missing_field = True + + if skip_missing_field: + pass + else: + raise ValidationError(f"Invalid top level field list. Expected " + f"{allkeys} got {keys}.") if (self.vrsn.major < 2 and self.vrsn.minor < 1 and self.ilk in (Ilks.qry, Ilks.rpy, Ilks.pro, Ilks.bar, Ilks.exn)): diff --git a/tests/core/test_serdering.py b/tests/core/test_serdering.py index 29eabf379..f826b9c66 100644 --- a/tests/core/test_serdering.py +++ b/tests/core/test_serdering.py @@ -2087,6 +2087,17 @@ def test_serderkeri_bar(): """End Test""" +def test_serderkeri_exn_old(): + """Test SerderKERI exn msg""" + serder = SerderKERI(raw=b'{"v":"KERI10JSON000088_","t":"exn",' + b'"d":"EMuAoRSE4zREKKYyvuNeYCDM9_MwPQIh1WL0' + b'cFC4e-bU","i":"","p":"","dt":"","r":"","q":{},"a":[],"e":{}}', ilk=kering.Ilks.exn) + + assert serder.verify() # because pre is empty + assert serder.ilk == kering.Ilks.exn + assert serder.pre == '' + assert serder.prior == '' + def test_serderkeri_exn(): """Test SerderKERI exn msg""" @@ -2492,6 +2503,7 @@ def test_serdery_noversion(): test_serderkeri_pro() test_serderkeri_bar() test_serderkeri_exn() + test_serderkeri_exn_old() test_serderkeri_vcp() test_serderacdc() test_serdery() From b43bf71a59528987feafbdc9420c322e72a5a683 Mon Sep 17 00:00:00 2001 From: Arshdeep Date: Thu, 13 Mar 2025 20:50:27 +0530 Subject: [PATCH 61/61] allows missing rp field for exns when it is the only missing field --- src/keri/peer/exchanging.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/keri/peer/exchanging.py b/src/keri/peer/exchanging.py index 5302efd22..662cfef54 100644 --- a/src/keri/peer/exchanging.py +++ b/src/keri/peer/exchanging.py @@ -228,7 +228,10 @@ def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): self.hby.db.erpy.pin(keys=(pdig,), val=saider) self.hby.db.exns.put(keys=(dig,), val=serder) - recipient = serder.ked['rp'] + # special handling for 1.1.18 -> 1.1.32 + recipient = None + if 'rp' in serder.ked: + recipient = serder.ked['rp'] sender = serder.ked['i'] route = serder.ked['r'] logger.info("Saved exn event route = %s SAID = %s sender %s -> recipient %s",