diff --git a/src/keri/app/cli/commands/escrow/clear.py b/src/keri/app/cli/commands/escrow/clear.py index 5d030b91f..dbf08e986 100644 --- a/src/keri/app/cli/commands/escrow/clear.py +++ b/src/keri/app/cli/commands/escrow/clear.py @@ -9,6 +9,7 @@ from hio.base import doing from keri import help from keri.app.cli.common import existing +from keri.vdr import viring logger = help.ogler.getLogger() @@ -47,6 +48,9 @@ def clear(tymth, tock=0.0, **opts): 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 index 418a82e62..7725c063a 100644 --- a/src/keri/app/cli/commands/escrow/list.py +++ b/src/keri/app/cli/commands/escrow/list.py @@ -52,6 +52,15 @@ def escrows(tymth, tock=0.0, **opts): reger = viring.Reger(name=hby.name, db=hby.db, temp=False) escrows = dict() + + # KEL / Baser escrows - counts only + + 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 == "out-of-order-events": oots = list() key = ekey = b'' # both start same. when not same means escrows found @@ -124,6 +133,50 @@ def escrows(tymth, tock=0.0, **opts): escrows["likely-duplicitous-events"] = ldes + if (not escrow) or escrow == "unverified-event-indexed-couples": + escrows["unverified-event-indexed-couples"] = sum(1 for key, _ in hby.db.uwes.getItemIter()) + + if (not escrow) or escrow == "query-not-found": + escrows["query-not-found"] = sum(1 for key, _ in hby.db.qnfs.getItemIter()) + + if (not escrow) or escrow == "partially-delegated-events": + escrows["partially-delegated-events"] = sum(1 for key, _ in hby.db.pdes.getItemIter()) + + 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 + + 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.getTweItemIter()) + + if (not escrow) or escrow == "tel-anchorless": + escrows["tel-anchorless"] = sum(1 for key, _ in reger.getTaeItemIter()) + if (not escrow) or escrow == "missing-registry-escrow": creds = list() for (said,), dater in reger.mre.getItemIter(): @@ -148,11 +201,34 @@ def escrows(tymth, tock=0.0, **opts): escrows["missing-schema-escrow"] = creds - print(json.dumps(escrows, indent=2)) + 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-partial-witness-escrow': - for (regk, snq), (prefixer, seqner, saider) in reger.tpwe.getItemIter(): - pass + if (not escrow) or escrow == "tel-event-dissemination": + escrows["tel-event-dissemination"] = sum(1 for key, _ in reger.tede.getItemIter()) + + if (not escrow) or escrow == "registry-missing-anchor": + escrows["registry-missing-anchor"] = sum(1 for key, _ in reger.txnsb.escrowdb.getItemIter(keys=("registry-mae", ""))) + + if (not escrow) or escrow == "registry-out-of-order": + escrows["registry-out-of-order"] = sum(1 for key, _ in reger.txnsb.escrowdb.getItemIter(keys=("registry-ooo", ""))) + + if (not escrow) or escrow == "credential-missing-registry": + escrows["credential-missing-registry"] = sum(1 for key, _ in reger.txnsb.escrowdb.getItemIter(keys=("credential-mre", ""))) + + if (not escrow) or escrow == "credential-missing-anchor": + escrows["credential-missing-anchor"] = sum(1 for key, _ in reger.txnsb.escrowdb.getItemIter(keys=("credential-mae", ""))) + + if (not escrow) or escrow == "credential-out-of-order": + escrows["credential-out-of-order"] = sum(1 for key, _ in reger.txnsb.escrowdb.getItemIter(keys=("credential-ooo", ""))) + + print(json.dumps(escrows, indent=2)) except ConfigurationError as e: print(f"identifier prefix for {name} does not exist, incept must be run first", ) diff --git a/src/keri/vdr/viring.py b/src/keri/vdr/viring.py index 747820818..47393164e 100644 --- a/src/keri/vdr/viring.py +++ b/src/keri/vdr/viring.py @@ -18,10 +18,10 @@ from ..core import coring, serdering, indexing, counting from ..db import dbing, basing from ..db.dbing import snKey -from ..help import helping -from ..vc import proving from ..vdr import eventing +from .. import help +logger = help.ogler.getLogger() class rbdict(dict): """ Reger backed read through cache for registry state @@ -798,6 +798,13 @@ def delTwe(self, key): """ return self.delVal(self.twes, key) + def getTweItemIter(self): + """ + Return iterator of all items in .twes + + """ + return self.getTopItemIter(self.twes) + def putTae(self, key, val): """ Use snKey() @@ -885,6 +892,36 @@ def delOot(self, key): """ return self.delVal(self.oots, key) + def clearEscrows(self): + """Clear credential event escrows""" + 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.getTweItemIter(): + count += 1 + self.delTwe(k) + logger.info(f"TEL: Cleared {count} partially witnessed escrows.") + + count = 0 + for (k, _) in self.getTaeItemIter(): + 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') + ]: + sub.trim() def putAnc(self, key, val): """ diff --git a/tests/app/cli/test_kli_commands.py b/tests/app/cli/test_kli_commands.py index 4db45e43a..319fcd45c 100644 --- a/tests/app/cli/test_kli_commands.py +++ b/tests/app/cli/test_kli_commands.py @@ -245,13 +245,38 @@ def test_standalone_kli_commands(helpers, capsys): directing.runController(doers=doers) capesc = capsys.readouterr() assert capesc.out == ('{\n' + ' "unverified-receipts": 0,\n' + ' "verified-receipts": 0,\n' ' "out-of-order-events": [],\n' ' "partially-witnessed-events": [],\n' ' "partially-signed-events": [],\n' ' "likely-duplicitous-events": [],\n' + ' "unverified-event-indexed-couples": 0,\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' + ' "registry-missing-anchor": 0,\n' + ' "registry-out-of-order": 0,\n' + ' "credential-missing-registry": 0,\n' + ' "credential-missing-anchor": 0,\n' + ' "credential-out-of-order": 0\n' '}\n') diff --git a/tests/vdr/test_viring.py b/tests/vdr/test_viring.py index 2f083fb3a..4fbdb4f06 100644 --- a/tests/vdr/test_viring.py +++ b/tests/vdr/test_viring.py @@ -11,7 +11,10 @@ import lmdb +from keri import kering +from keri.core import coring from keri.core.coring import Diger, versify, Kinds +from keri.core.serdering import SerderACDC from keri.db.dbing import openLMDB, dgKey, snKey from keri.vdr.viring import Reger @@ -345,6 +348,65 @@ def test_clone(): b'AAAAAAAAABCEzpq06UecHwzy-K9FpNoRxCJp2wIGM9u2Edk-PLMZ1H4') +def test_clearEscrows(): + with openLMDB(cls=Reger) as db: + regk = "EAWdT7a7fZwRz0jiZ0DJxZEM3vsNbLDPEUk-ODnif3O0".encode("utf-8") + sn = 0 + ooKey = snKey(regk, sn) + vs = versify(kind=coring.Kinds.json, size=20) + rarb = "BBjzaUuRMwh1ivT5BQrqNhbvx82lB-ofrHVHjL3WADbA".encode("utf-8") + vcp = dict(v=vs, i=regk.decode("utf-8"), + s="{:x}".format(sn), b=[rarb.decode("utf-8")], + t="vcp") + + vcpb = json.dumps(vcp, separators=(",", ":"), ensure_ascii=False).encode("utf-8") + vdig = Diger(ser=vcpb) + + db.putOot(ooKey, val=vdig.qb64b) + db.putTwe(ooKey, val=vdig.qb64b) + db.putTae(ooKey, val=vdig.qb64b) + + pre = 'k' + db.mre.put(keys=(pre, ), val=coring.Dater()) + db.mce.put(keys=(pre, ), val=coring.Dater()) + db.mse.put(keys=(pre, ), val=coring.Dater()) + + creder = SerderACDC(makify=True, proto=kering.Protocols.acdc, verify=False) + db.cmse.put(("a", "b"), val=creder) + + prefixer = coring.Prefixer(qb64="EAD919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I") + seqner = coring.Seqner(sn=0) + saider = coring.Saider(qb64="EAD919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I") + db.tpwe.add(("a", "b"), (prefixer, seqner, saider)) + db.tmse.add(("a", "b"), (prefixer, seqner, saider)) + db.tede.add(("a", "b"), (prefixer, seqner, saider)) + + assert db.getOot(ooKey) == vdig.qb64b + assert db.getTwe(ooKey) == vdig.qb64b + assert db.getTae(ooKey) == vdig.qb64b + assert db.mre.get((pre, )) is not None + assert db.mce.get((pre, )) is not None + assert db.mse.get((pre, )) is not None + assert db.cmse.cntAll() == 1 + assert db.tpwe.cntAll() == 1 + assert db.tmse.cntAll() == 1 + assert db.tede.cntAll() == 1 + + db.clearEscrows() + + assert db.getOot(ooKey) is None + assert db.getTwe(ooKey) is None + assert db.getTae(ooKey) is None + assert db.mre.get((pre, )) is None + assert db.mce.get((pre, )) is None + assert db.mse.get((pre, )) is None + assert db.cmse.cntAll() == 0 + assert db.tpwe.cntAll() == 0 + assert db.tmse.cntAll() == 0 + assert db.tede.cntAll() == 0 + + if __name__ == "__main__": test_issuer() test_clone() + test_clearEscrows()