Skip to content

Commit

Permalink
adds escrow clear
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin Griffin <[email protected]>
  • Loading branch information
m00sey committed Jan 17, 2025
1 parent 3a7ba5e commit f9fff1c
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/keri/app/cli/commands/escrow/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import argparse

parser = argparse.ArgumentParser(description="A collection of escrow operations")
52 changes: 52 additions & 0 deletions src/keri/app/cli/commands/escrow/clear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- encoding: utf-8 -*-
"""
KERI
keri.kli.commands.escrow module
"""
import argparse

from hio.base import doing
from keri import help
from keri.app.cli.common import existing

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', 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

with existing.existingHby(name=name, base=base, bran=bran) as hby:
hby.db.clearEscrows()
159 changes: 159 additions & 0 deletions src/keri/app/cli/commands/escrow/list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# -*- encoding: utf-8 -*-
"""
KERI
keri.kli.commands.escrow module
"""
import argparse
import json

from hio.base import doing

from keri import help
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:
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.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 == "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 == "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 == "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 == "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
40 changes: 34 additions & 6 deletions src/keri/db/basing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ def migrate(self):
# 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, ver_no_prerelease) > 0:
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
Expand All @@ -1367,16 +1367,45 @@ def migrate(self):

mod = importlib.import_module(modName)
try:
print(f"running migration {modName}")
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())
self.version = version # update database version after successful migration

# update database version after successful migration
self.version = version

self.version = keri.__version__

def clearEscrows(self):
"""
Clear all escrows
"""
for (k, _) in self.getUreItemIter():
self.delUres(key=k)
for (k, _) in self.getVreItemIter():
self.delVres(key=k)
for (k, _) in self.getPseItemIter():
self.delPses(key=k)
for (k, _) in self.getPweItemIter():
self.delPwes(key=k)
for (k, _) in self.getUweItemIter():
self.delUwes(key=k)
for (k, _) in self.getOoeItemIter():
self.delOoes(key=k)
for (k, _) in self.getLdeItemIter():
self.delLdes(key=k)
for (pre, said), edig in self.qnfs.getItemIter():
self.qnfs.rem(keys=(pre, said))


for escrow in [self.qnfs, self.misfits, self.delegables, self.pdes, self.udes, self.rpes, self.epsd, self.eoobi,
self.dpub, self.gpwe, self.gdee, self.dpwe, self.gpse, self.epse, self.dune]:
escrow.trim()

@property
def current(self):
""" Current property determines if we are at the current database migration state.
Expand All @@ -1391,10 +1420,9 @@ def current(self):
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, ver_no_prerelease) == 1:
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__}")

Expand Down Expand Up @@ -1426,7 +1454,7 @@ def complete(self, name=None):
dater = self.migs.get(keys=(mig,))
migrations.append((mig, dater))
else:
for version, migs in MIGRATIONS: # check all migrations for each version
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,))))
Expand Down Expand Up @@ -2349,7 +2377,7 @@ def getUreLast(self, key):

def getUreItemIter(self, key=b''):
"""
Use sgKey()
Use snKey()
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
Expand Down
2 changes: 1 addition & 1 deletion tests/app/cli/test_kli_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ 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)
Expand Down
Loading

0 comments on commit f9fff1c

Please sign in to comment.