diff --git a/images/keripy.base.dockerfile b/images/keripy.base.dockerfile new file mode 100644 index 000000000..23de45f8d --- /dev/null +++ b/images/keripy.base.dockerfile @@ -0,0 +1,15 @@ +# Builder layer +FROM python:3.12-alpine as builder + +# Install compilation dependencies +RUN apk --no-cache add \ + bash \ + alpine-sdk \ + libffi-dev \ + libsodium \ + libsodium-dev + +SHELL ["/bin/bash", "-c"] + +# Setup Rust for blake3 dependency build +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y diff --git a/src/keri/app/agenting.py b/src/keri/app/agenting.py index 2fd13cf49..ad164a9b3 100644 --- a/src/keri/app/agenting.py +++ b/src/keri/app/agenting.py @@ -227,8 +227,9 @@ def witDo(self, tymth=None, tock=0.0): msg = self.msgs.popleft() pre = msg["pre"] sn = msg["sn"] if "sn" in msg else None + auths = msg["auths"] if "auths" in msg else None - yield from self.receipt(pre, sn) + yield from self.receipt(pre, sn, auths) self.cues.push(msg) yield self.tock @@ -616,12 +617,10 @@ def sendDo(self, tymth=None, tock=0.0, **opts): _ = (yield self.tock) - total = len(witers) - count = 0 - while count < total: - for witer in witers: - count += len(witer.sent) - _ = (yield self.tock) + while witers: + witer = witers.pop() + while not witer.idle: + _ = (yield self.tock) self.remove(witers) self.cues.push(evt) diff --git a/src/keri/app/cli/commands/aid.py b/src/keri/app/cli/commands/aid.py new file mode 100644 index 000000000..856f65dda --- /dev/null +++ b/src/keri/app/cli/commands/aid.py @@ -0,0 +1,58 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse + +from hio import help +from hio.base import doing + +from keri.app.cli.common import existing +from keri.kering import ConfigurationError + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Print the AID for a given alias') +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, + required=True) +parser.add_argument('--passcode', '-p', help='21 character encryption passcode for keystore (is not saved)', + dest="bran", default=None) # passcode => bran + + +def handler(args): + kwa = dict(args=args) + return [doing.doify(status, **kwa)] + + +def status(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: + if alias is None: + alias = existing.aliasInput(hby) + + hab = hby.habByName(alias) + if hab is None: + print(f"{alias} is not a valid alias for an identifier") + + print(hab.pre) + + 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/delegate/confirm.py b/src/keri/app/cli/commands/delegate/confirm.py index 374f017ac..a0ddb7525 100644 --- a/src/keri/app/cli/commands/delegate/confirm.py +++ b/src/keri/app/cli/commands/delegate/confirm.py @@ -16,6 +16,7 @@ from keri import core from keri.core import coring, serdering from keri.db import dbing +from keri.help import helping from keri.peer import exchanging logger = help.ogler.getLogger() @@ -32,6 +33,10 @@ parser.add_argument("--interact", "-i", help="anchor the delegation approval in an interaction event. " "Default is to use a rotation event.", action="store_true") parser.add_argument("--auto", "-Y", help="auto approve any delegation request non-interactively", action="store_true") +parser.add_argument("--authenticate", '-z', help="Prompt the controller for authentication codes for each witness", + action='store_true') +parser.add_argument('--code', help=': formatted witness auth codes. Can appear multiple times', + default=[], action="append", required=False) def confirm(args): @@ -47,15 +52,18 @@ def confirm(args): alias = args.alias interact = args.interact auto = args.auto + authenticate = args.authenticate + codes = args.code - confirmDoer = ConfirmDoer(name=name, base=base, alias=alias, bran=bran, interact=interact, auto=auto) + confirmDoer = ConfirmDoer(name=name, base=base, alias=alias, bran=bran, interact=interact, auto=auto, + authenticate=authenticate, codes=codes) doers = [confirmDoer] return doers class ConfirmDoer(doing.DoDoer): - def __init__(self, name, base, alias, bran, interact=False, auto=False): + def __init__(self, name, base, alias, bran, interact=False, auto=False, authenticate=False, codes=None): hby = existing.setupHby(name=name, base=base, bran=bran) self.hbyDoer = habbing.HaberyDoer(habery=hby) # setup doer self.witq = agenting.WitnessInquisitor(hby=hby) @@ -63,6 +71,8 @@ def __init__(self, name, base, alias, bran, interact=False, auto=False): self.counselor = grouping.Counselor(hby=hby) self.notifier = notifying.Notifier(hby=hby) self.mux = grouping.Multiplexor(hby=hby, notifier=self.notifier) + self.authenticate = authenticate + self.codes = codes if codes is not None else [] exc = exchanging.Exchanger(hby=hby, handlers=[]) delegating.loadHandlers(hby=hby, exc=exc, notifier=self.notifier) @@ -173,7 +183,19 @@ def confirmDo(self, tymth, tock=0.0): else: hab.rotate(data=[anchor]) - witDoer = agenting.WitnessReceiptor(hby=self.hby) + auths = {} + if self.authenticate: + for arg in self.codes: + (wit, code) = arg.split(":") + auths[wit] = f"{code}#{helping.nowIso8601()}" + + for wit in hab.kever.wits: + if wit in auths: + continue + code = input(f"Entire code for {wit}: ") + auths[wit] = f"{code}#{helping.nowIso8601()}" + + witDoer = agenting.WitnessReceiptor(hby=self.hby, auths=auths) self.extend(doers=[witDoer]) self.toRemove.append(witDoer) yield self.tock diff --git a/src/keri/app/cli/commands/incept.py b/src/keri/app/cli/commands/incept.py index 3576f797b..4af084c73 100644 --- a/src/keri/app/cli/commands/incept.py +++ b/src/keri/app/cli/commands/incept.py @@ -117,6 +117,8 @@ def mergeArgsWithFile(args): incept_opts.estOnly = args.est_only if args.data is not None: incept_opts.data = config.parseData(args.data) + if args.delpre is not None: + incept_opts.delpre = args.delpre return incept_opts diff --git a/src/keri/app/cli/commands/mailbox/add.py b/src/keri/app/cli/commands/mailbox/add.py new file mode 100644 index 000000000..67abf1990 --- /dev/null +++ b/src/keri/app/cli/commands/mailbox/add.py @@ -0,0 +1,135 @@ +# -*- encoding: utf-8 -*- +""" +KERI +keri.kli.commands module + +""" +import argparse + +from hio import help +from hio.base import doing +from hio.help import Hict + +from keri import kering +from keri.app import connecting, habbing, forwarding +from keri.app.agenting import httpClient, WitnessPublisher +from keri.app.cli.common import existing +from keri.core import serdering + +logger = help.ogler.getLogger() + +parser = argparse.ArgumentParser(description='Add mailbox role') +parser.set_defaults(handler=lambda args: add(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 +parser.add_argument("--mailbox", '-w', help="the mailbox AID or alias to add", required=True) + + +def add(args): + """ Command line handler for adding an aid to a watcher's list of AIds to watch + + Parameters: + args(Namespace): parsed command line arguments + + """ + + ed = AddDoer(name=args.name, + alias=args.alias, + base=args.base, + bran=args.bran, + mailbox=args.mailbox) + return [ed] + + +class AddDoer(doing.DoDoer): + + def __init__(self, name, alias, base, bran, mailbox): + self.hby = existing.setupHby(name=name, base=base, bran=bran) + self.hab = self.hby.habByName(alias) + self.org = connecting.Organizer(hby=self.hby) + self.witpub = WitnessPublisher(hby=self.hby) + + if mailbox in self.hby.kevers: + mbx = mailbox + else: + mbx = self.org.find("alias", mailbox) + if len(mbx) != 1: + raise ValueError(f"invalid mailbox {mailbox}") + mbx = mbx[0]['id'] + + if not mbx: + raise ValueError(f"unknown mailbox {mailbox}") + + self.mailbox = mbx + + doers = [doing.doify(self.addDo), self.witpub] + + super(AddDoer, self).__init__(doers=doers) + + def addDo(self, tymth, tock=0.0): + """ Grant credential by creating /ipex/grant exn message + + 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 isinstance(self.hab, habbing.GroupHab): + raise ValueError("watchers for multisig AIDs not currently supported") + + kel = self.hab.replay() + data = dict(cid=self.hab.pre, + role=kering.Roles.mailbox, + eid=self.mailbox) + + route = "/end/role/add" + msg = self.hab.reply(route=route, data=data) + self.hab.psr.parseOne(ims=(bytes(msg))) # make copy to preserve + + fargs = dict([("kel", kel.decode("utf-8")), + ("rpy", msg.decode("utf-8"))]) + + headers = (Hict([ + ("Content-Type", "multipart/form-data"), + ])) + + client, clientDoer = httpClient(self.hab, self.mailbox) + self.extend([clientDoer]) + + client.request( + method="POST", + path=f"{client.requester.path}/mailboxes", + headers=headers, + fargs=fargs + ) + while not client.responses: + yield self.tock + + rep = client.respond() + if rep.status == 200: + msg = self.hab.replyEndRole(cid=self.hab.pre, role=kering.Roles.mailbox) + self.witpub.msgs.append(dict(pre=self.hab.pre, msg=bytes(msg))) + + while not self.witpub.cues: + yield self.tock + + print(f"Mailbox {self.mailbox} added for {self.hab.name}") + + else: + print(rep.status, rep.data) + + self.remove([clientDoer, self.witpub]) diff --git a/src/keri/app/cli/commands/oobi/generate.py b/src/keri/app/cli/commands/oobi/generate.py index f487f3546..e35a53354 100644 --- a/src/keri/app/cli/commands/oobi/generate.py +++ b/src/keri/app/cli/commands/oobi/generate.py @@ -81,3 +81,16 @@ def generate(tymth, tock=0.0, **opts): url = urls[kering.Schemes.http] if kering.Schemes.http in urls else urls[kering.Schemes.https] up = urlparse(url) print(f"{up.scheme}://{up.hostname}:{up.port}/oobi/{hab.pre}/controller") + elif role in (kering.Roles.mailbox,): + for (_, _, eid), end in hab.db.ends.getItemIter(keys=(hab.pre, kering.Roles.mailbox, )): + if not (end.allowed and end.enabled is not False): + continue + + urls = hab.fetchUrls(eid=eid, scheme=kering.Schemes.http) or hab.fetchUrls(eid=hab.pre, + scheme=kering.Schemes.https) + if not urls: + print(f"{alias} identifier {hab.pre} does not have any mailbox endpoints") + return + url = urls[kering.Schemes.http] if kering.Schemes.http in urls else urls[kering.Schemes.https] + up = urlparse(url) + print(f"{up.scheme}://{up.hostname}:{up.port}/oobi/{hab.pre}/mailbox/{eid}") diff --git a/src/keri/app/cli/commands/status.py b/src/keri/app/cli/commands/status.py index 662a6b625..96f531828 100644 --- a/src/keri/app/cli/commands/status.py +++ b/src/keri/app/cli/commands/status.py @@ -10,7 +10,7 @@ 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/witness/authenticate.py b/src/keri/app/cli/commands/witness/authenticate.py index 126fc0417..1758093ce 100644 --- a/src/keri/app/cli/commands/witness/authenticate.py +++ b/src/keri/app/cli/commands/witness/authenticate.py @@ -16,7 +16,6 @@ from keri.app import httping, connecting from keri.app.agenting import httpClient from keri.app.cli.common import existing -from keri.app.httping import CESR_CONTENT_TYPE from keri.core import coring logger = help.ogler.getLogger() @@ -32,6 +31,8 @@ parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran parser.add_argument("--witness", '-w', help="the witness AID or alias to authenticate against", required=True) +parser.add_argument("--url-only", '-u', dest="url", help="display only the URL (no QR Code).", required=False, + action="store_true") def auth(args): @@ -46,16 +47,18 @@ def auth(args): alias=args.alias, base=args.base, bran=args.bran, - witness=args.witness) + witness=args.witness, + urlOnly=args.url) return [ed] class AuthDoer(doing.DoDoer): - def __init__(self, name, alias, base, bran, witness): + def __init__(self, name, alias, base, bran, witness, urlOnly): self.hby = existing.setupHby(name=name, base=base, bran=bran) self.hab = self.hby.habByName(alias) self.org = connecting.Organizer(hby=self.hby) + self.urlOnly = urlOnly if witness in self.hby.kevers: wit = witness @@ -94,9 +97,17 @@ def authDo(self, tymth, tock=0.0): for msg in self.hab.db.clonePreIter(pre=self.hab.pre): body.extend(msg) + fargs = dict([("kel", body.decode("utf-8"))]) + + if self.hab.kever.delegated: + delkel = bytearray() + for msg in self.hab.db.clonePreIter(self.hab.kever.delpre): + delkel.extend(msg) + + fargs['delkel'] = delkel.decode("utf-8") + headers = (Hict([ - ("Content-Type", "application/cesr"), - ("Content-Length", len(body)), + ("Content-Type", "multipart/form-data") ])) client, clientDoer = httpClient(self.hab, self.witness) @@ -106,7 +117,7 @@ def authDo(self, tymth, tock=0.0): method="POST", path=f"{client.requester.path}/aids", headers=headers, - body=bytes(body) + fargs=fargs ) while not client.responses: yield self.tock @@ -120,10 +131,12 @@ def authDo(self, tymth, tock=0.0): d = coring.Matter(qb64=self.hab.decrypt(m.raw)) otpurl = f"otpauth://totp/KERIpy:{self.witness}?secret={d.raw.decode('utf-8')}&issuer=KERIpy" - qr = qrcode.QRCode() - qr.add_data(otpurl) + if not self.urlOnly: + qr = qrcode.QRCode() + qr.add_data(otpurl) + + qr.print_ascii() - qr.print_ascii() print(otpurl) else: diff --git a/src/keri/app/cli/common/incepting.py b/src/keri/app/cli/common/incepting.py index 6a0789c91..6fe211fa3 100644 --- a/src/keri/app/cli/common/incepting.py +++ b/src/keri/app/cli/common/incepting.py @@ -28,4 +28,6 @@ def addInceptingArgs(parser): help='only allow establishment events in KEL for this prefix') parser.add_argument('--data', '-d', default=None, required=False, action="store", help='Anchor data, \'@\' allowed',) + parser.add_argument('--delpre', '-di', default=None, required=False, action="store", + help='Delegator AID for delegated identfiers',) diff --git a/src/keri/app/delegating.py b/src/keri/app/delegating.py index fcbdb053b..8d9e4c194 100644 --- a/src/keri/app/delegating.py +++ b/src/keri/app/delegating.py @@ -28,7 +28,7 @@ class Anchorer(doing.DoDoer): """ - def __init__(self, hby, proxy=None, **kwa): + def __init__(self, hby, proxy=None, auths=None, **kwa): """ For the current event, gather the current set of witnesses, send the event, gather all receipts and send them to all other witnesses @@ -45,11 +45,12 @@ def __init__(self, hby, proxy=None, **kwa): self.witq = agenting.WitnessInquisitor(hby=hby) self.witDoer = agenting.Receiptor(hby=self.hby) self.proxy = proxy + self.auths = auths super(Anchorer, self).__init__(doers=[self.witq, self.witDoer, self.postman, doing.doify(self.escrowDo)], **kwa) - def delegation(self, pre, sn=None, proxy=None): + def delegation(self, pre, sn=None, proxy=None, auths=None): if pre not in self.hby.habs: raise kering.ValidationError(f"{pre} is not a valid local AID for delegation") @@ -63,13 +64,14 @@ def delegation(self, pre, sn=None, proxy=None): raise kering.ValidationError(f"delegator {delpre} not found, unable to process delegation") sn = sn if sn is not None else hab.kever.sner.num + self.auths = auths if auths is not None else self.auths # load the event and signatures evt = hab.makeOwnEvent(sn=sn) # Send exn message for notification purposes srdr = serdering.SerderKERI(raw=evt) - self.witDoer.msgs.append(dict(pre=pre, sn=srdr.sn)) + self.witDoer.msgs.append(dict(pre=pre, sn=srdr.sn, auths=self.auths)) self.hby.db.dpwe.pin(keys=(srdr.pre, srdr.said), val=srdr) def complete(self, prefixer, seqner, saider=None): diff --git a/src/keri/app/httping.py b/src/keri/app/httping.py index d3ac5e8ac..346b870e0 100644 --- a/src/keri/app/httping.py +++ b/src/keri/app/httping.py @@ -233,6 +233,9 @@ def request(self, method, url, body=None, headers=None): print(f"error establishing client connection={e}") return None + if hasattr(body, "encode"): + body = body.encode("utf-8") + client.request( method=method, path=f"{purl.path}?{purl.query}", diff --git a/src/keri/app/indirecting.py b/src/keri/app/indirecting.py index 32dc0b190..4dedb432a 100644 --- a/src/keri/app/indirecting.py +++ b/src/keri/app/indirecting.py @@ -971,7 +971,7 @@ def __iter__(self): def __next__(self): if self.iter is None: if self.cues: - cue = self.cues.pull() # self.cues.popleft() + cue = self.cues.pull() serder = cue["serder"] if serder.said == self.said: kin = cue["kin"] diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index 5bea6584b..fc2f51009 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -989,8 +989,8 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, code = f"{s}{code[1:hs]}" ss = 4 else: - raise InvalidVarRawSizeError(f"Unsupported raw size for " - f"{code=}.") + raise InvalidVarRawSizeError(f"Unsupported raw size for large " + f"{code=}. {size} <= {64 ** 4 - 1}") else: raise InvalidVarRawSizeError(f"Unsupported variable raw size " f"{code=}.") @@ -3926,8 +3926,10 @@ class CounterCodex: SadPathSigGroups: str = '-J' # Composed Base64 Group path+TransIdxSigGroup of SAID of content RootSadPathSigGroups: str = '-K' # Composed Base64 Group, root(path)+SaidPathCouples PathedMaterialGroup: str = '-L' # Composed Grouped Pathed Material Quadlet (4 char each) + BigPathedMaterialGroup: str = '-0L' # Composed Grouped Pathed Material Quadlet (4 char each) AttachmentGroup: str = '-V' # Composed Grouped Attached Material Quadlet (4 char each) BigAttachmentGroup: str = '-0V' # Composed Grouped Attached Material Quadlet (4 char each) + ESSRPayloadGroup: str = '-Z' # ESSR Payload Group, dig of content+Texter group KERIACDCGenusVersion: str = '--AAA' # KERI ACDC Protocol Stack CESR Version def __iter__(self): @@ -3995,7 +3997,9 @@ class Counter: '-J': Sizage(hs=2, ss=2, fs=4, ls=0), '-K': Sizage(hs=2, ss=2, fs=4, ls=0), '-L': Sizage(hs=2, ss=2, fs=4, ls=0), + '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), '-V': Sizage(hs=2, ss=2, fs=4, ls=0), + '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0), } diff --git a/src/keri/core/counting.py b/src/keri/core/counting.py index cd14e01cd..404b9b69b 100644 --- a/src/keri/core/counting.py +++ b/src/keri/core/counting.py @@ -66,8 +66,10 @@ class CounterCodex_1_0(MapDom): SadPathSigGroups: str = '-J' # Composed Base64 Group path+TransIdxSigGroup of SAID of content RootSadPathSigGroups: str = '-K' # Composed Base64 Group, root(path)+SaidPathCouples PathedMaterialGroup: str = '-L' # Composed Grouped Pathed Material Quadlet (4 char each) + BigPathedMaterialGroup: str = '-0L' # Composed Grouped Pathed Material Quadlet (4 char each) AttachmentGroup: str = '-V' # Composed Grouped Attached Material Quadlet (4 char each) BigAttachmentGroup: str = '-0V' # Composed Grouped Attached Material Quadlet (4 char each) + ESSRPayloadGroup: str = '-Z' # ESSR Payload Group, dig of content+Texter group KERIACDCGenusVersion: str = '--AAA' # KERI ACDC Protocol Stack CESR Version @@ -345,6 +347,7 @@ class Counter: '-J': Sizage(hs=2, ss=2, fs=4, ls=0), '-K': Sizage(hs=2, ss=2, fs=4, ls=0), '-L': Sizage(hs=2, ss=2, fs=4, ls=0), + '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), '-V': Sizage(hs=2, ss=2, fs=4, ls=0), '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0), diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index 6b4e743f5..dd9cb2244 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -5065,8 +5065,6 @@ def processEscrowOutOfOrders(self): # still waiting on missing prior event to validate if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -5221,8 +5219,6 @@ def processEscrowPartialSigs(self): # still waiting on missing sigs or missing seal to validate if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than waiting on sigs or seal so remove from escrow @@ -5393,8 +5389,6 @@ def processEscrowPartialWigs(self): # still waiting on missing witness sigs if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than waiting on sigs or seal so remove from escrow @@ -5518,8 +5512,6 @@ def processEscrowUnverWitness(self): # only happens if we process above if logger.isEnabledFor(logging.DEBUG): # adds exception data logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -5691,8 +5683,6 @@ def processEscrowUnverNonTrans(self): # only happens if we process above if logger.isEnabledFor(logging.DEBUG): # adds exception data logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -5812,8 +5802,6 @@ def processEscrowDelegables(self): # still waiting on missing delegation approval if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -5930,8 +5918,6 @@ def processQueryNotFound(self): # still waiting on missing prior event to validate if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -6221,8 +6207,6 @@ def processEscrowUnverTrans(self): # only happens if we process above if logger.isEnabledFor(logging.DEBUG): # adds exception data logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than out of order so remove from OO escrow @@ -6355,8 +6339,6 @@ def processEscrowDuplicitous(self): # still can't determine if duplicitous if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery unescrow failed: %s", ex.args[0]) - else: - logger.error("Kevery unescrow failed: %s", ex.args[0]) except Exception as ex: # log diagnostics errors etc # error other than likely duplicitous so remove from escrow diff --git a/src/keri/core/parsing.py b/src/keri/core/parsing.py index 9273f6255..4faa7f36a 100644 --- a/src/keri/core/parsing.py +++ b/src/keri/core/parsing.py @@ -8,7 +8,7 @@ import logging from .coring import (Ilks, CtrDex, Counter, Seqner, Cigar, - Dater, Verfer, Prefixer, Saider, Pather) + Dater, Verfer, Prefixer, Saider, Pather, Texter) from .indexing import (Siger, ) from . import serdering from .. import help @@ -445,7 +445,7 @@ def allParsator(self, ims=None, framed=None, pipeline=None, kvy=None, if logger.isEnabledFor(logging.DEBUG): logger.exception("Parser msg non-extraction error: %s", ex) else: - logger.error("Parser msg non-extraction error: %s", ex) + logger.exception("Parser msg non-extraction error: %s", ex) yield return True @@ -530,7 +530,7 @@ def onceParsator(self, ims=None, framed=None, pipeline=None, kvy=None, if logger.isEnabledFor(logging.DEBUG): logger.exception("Kevery msg non-extraction error: %s", ex.args[0]) else: - logger.error("Kevery msg non-extraction error: %s", ex.args[0]) + logger.exception("Kevery msg non-extraction error: %s", ex.args[0]) finally: done = True @@ -620,7 +620,7 @@ def parsator(self, ims=None, framed=None, pipeline=None, kvy=None, tvy=None, if logger.isEnabledFor(logging.DEBUG): logger.exception("Parser msg non-extraction error: %s", ex.args[0]) else: - logger.error("Parser msg non-extraction error: %s", ex.args[0]) + logger.exception("Parser msg non-extraction error: %s", ex.args[0]) yield return True # should never return @@ -721,6 +721,7 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, # List of tuples from extracted SAD path sig groups from non-trans identifiers sadcigs = [] # each converted group is path plus list of non-trans sigs pathed = [] # grouped attachments targetting a subpath + essrs = [] # group texter pipelined = False # all attachments in one big pipeline counted group # extract and deserialize attachments try: # catch errors here to flush only counted part of stream @@ -919,16 +920,6 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, else: sadcigs.append(sigs) - elif ctr.code == CtrDex.SadPathSigGroups: - for code, sigs in self._sadPathSigGroup(ctr=ctr, - ims=ims, - cold=cold, - pipelined=pipelined): - if code == CtrDex.TransIdxSigGroups: - sadtsgs.append(sigs) - else: - sadcigs.append(sigs) - elif ctr.code == CtrDex.PathedMaterialGroup: # pathed ctr? # compute pipelined attached group size based on txt or bny pags = ctr.count * 4 if cold == Colds.txt else ctr.count * 3 @@ -939,6 +930,25 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, del ims[:pags] # strip off from ims pathed.append(pims) + elif ctr.code == CtrDex.BigPathedMaterialGroup: # pathed ctr? + # compute pipelined attached group size based on txt or bny + pags = ctr.count * 4 if cold == Colds.txt else ctr.count * 3 + while len(ims) < pags: # wait until rx full pipelned group + yield + + pims = ims[:pags] # copy out substream pipeline group + del ims[:pags] # strip off from ims + pathed.append(pims) + + elif ctr.code == CtrDex.ESSRPayloadGroup: + for i in range(ctr.count): + texter = yield from self._extractor(ims, + klas=Texter, + cold=cold, + abort=pipelined) + essrs.append(texter) + + else: raise kering.UnexpectedCountCodeError("Unsupported count" " code={}.".format(ctr.code)) @@ -1079,6 +1089,9 @@ def msgParsator(self, ims=None, framed=True, pipeline=False, if pathed: args["pathed"] = pathed + if essrs: + args["essrs"] = essrs + try: if cigars: exc.processEvent(cigars=cigars, **args) diff --git a/src/keri/core/serdering.py b/src/keri/core/serdering.py index 312bc4b5b..9c46826d0 100644 --- a/src/keri/core/serdering.py +++ b/src/keri/core/serdering.py @@ -427,8 +427,8 @@ class Serder: Ilks.bar: FieldDom(alls=dict(v='', t='',d='', dt='', r='', a=[]), saids={Saids.d: DigDex.Blake3_256}), - Ilks.exn: FieldDom(alls=dict(v='', t='', d='', i="", p="", - dt='', r='',q={}, a=[], e={}), + Ilks.exn: FieldDom(alls=dict(v='', t='', d='', i="", rp="", + p="", dt='', r='',q={}, a=[], e={}), saids={Saids.d: DigDex.Blake3_256}), Ilks.vcp: FieldDom(alls=dict(v='', t='',d='', i='', ii='', s='0', c=[], bt='0', b=[], n=''), diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index 1ceb53ce0..cf7fbd30d 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1063,6 +1063,8 @@ def reopen(self, **kwa): # TODO: clean self.epath = subing.IoSetSuber(db=self, subkey=".epath") + self.essrs = subing.CesrIoSetSuber(db=self, subkey=".essrs", klass=coring.Texter) + # accepted signed 12-word challenge response exn messages keys by prefix of signer # TODO: clean self.chas = subing.CesrIoSetSuber(db=self, subkey='chas.', klas=coring.Saider) diff --git a/src/keri/peer/exchanging.py b/src/keri/peer/exchanging.py index fcbefa8a8..ea96b7d41 100644 --- a/src/keri/peer/exchanging.py +++ b/src/keri/peer/exchanging.py @@ -71,6 +71,7 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): route = serder.ked["r"] sender = serder.ked["i"] pathed = kwargs["pathed"] if "pathed" in kwargs else [] + essrs = kwargs["essrs"] if "essrs" in kwargs else [] behavior = self.routes[route] if route in self.routes else None if tsgs is not None: @@ -110,6 +111,8 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): " for evt = {}.".format(serder.ked)) e = coring.Pather(path=["e"]) + + kwargs = dict() attachments = [] for p in pathed: pattach = bytearray(p) @@ -118,9 +121,23 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): np = pather.strip(e) attachments.append((np, pattach)) + kwargs["attachments"] = attachments + if essrs: + kwargs["essr"] = b''.join([texter.raw for texter in essrs]) + + if isinstance(serder.seals, str): + if 'essr' not in kwargs: + raise ValidationError("at least one essr attachment is required") + + essr = kwargs['essr'] + dig = serder.seals + diger = coring.Diger(qb64=dig) + if not diger.verify(ser=essr): + raise ValidationError(f"essr diger={diger.qb64} is invalid against content") + # Perform behavior specific verification, think IPEX chaining requirements try: - if not behavior.verify(serder=serder, attachments=attachments): + if not behavior.verify(serder=serder, **kwargs): logger.info(f"exn event for route {route} failed behavior verfication. said={serder.said}") logger.debug(f"event=\n{serder.pretty()}\n") return @@ -129,13 +146,13 @@ def processEvent(self, serder, tsgs=None, cigars=None, **kwargs): logger.info(f"Behavior for {route} missing or does not have verify for said={serder.said}") logger.debug(f"event=\n{serder.pretty()}\n") - # Always persis events - self.logEvent(serder, pathed, tsgs, cigars) + # Always persist events + self.logEvent(serder, pathed, tsgs, cigars, essrs) self.cues.append(dict(kin="saved", said=serder.said)) # Execute any behavior specific handling, not sure if this should be different than verify try: - behavior.handle(serder=serder, attachments=attachments) + behavior.handle(serder=serder, **kwargs) except AttributeError: logger.info(f"Behavior for {route} missing or does not have handle for said={serder.said}") logger.debug(f"event=\n{serder.pretty()}\n") @@ -187,9 +204,13 @@ def processEscrowPartialSigned(self): tsgs.append((prefixer, seqner, saider, sigers)) pathed = [bytearray(p.encode("utf-8")) for p in self.hby.db.epath.get(keys=(dig,))] + essrs = [texter for texter in self.hby.db.essrs.get(keys=(dig,))] try: - self.processEvent(serder=serder, tsgs=tsgs, pathed=pathed) + kwargs = dict() + if essrs: + kwargs["essrs"] = essrs + self.processEvent(serder=serder, tsgs=tsgs, pathed=pathed, **kwargs) except MissingSignatureError as ex: if logger.isEnabledFor(logging.DEBUG): @@ -210,12 +231,13 @@ def processEscrowPartialSigned(self): "creder=%s", serder.said) logger.debug(f"event=\n{serder.pretty()}\n") - def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): + def logEvent(self, serder, pathed=None, tsgs=None, cigars=None, essrs=None): dig = serder.said pdig = serder.ked['p'] pathed = pathed or [] tsgs = tsgs or [] cigars = cigars or [] + essrs = essrs or [] for prefixer, seqner, ssaider, sigers in tsgs: # iterate over each tsg quadkeys = (serder.said, prefixer.qb64, f"{seqner.sn:032x}", ssaider.qb64) @@ -226,6 +248,8 @@ def logEvent(self, serder, pathed=None, tsgs=None, cigars=None): saider = coring.Saider(qb64=serder.said) self.hby.db.epath.pin(keys=(dig,), vals=[bytes(p) for p in pathed]) + for texter in essrs: + self.hby.db.essrs.add(keys=(dig,), val=texter) if pdig: self.hby.db.erpy.pin(keys=(pdig,), val=saider) @@ -278,8 +302,9 @@ def complete(self, said): def exchange(route, - payload, sender, + payload=None, + diger=None, recipient=None, date=None, dig=None, @@ -292,6 +317,7 @@ def exchange(route, Parameters: route (str): to destination route of the message payload (list | dict): body of message to deliver to route + diger (Diger): qb64 digest of payload sender (str): qb64 AID of sender of the exn recipient (str) optional qb64 AID recipient of exn date (str): Iso8601 formatted date string to use for this request @@ -307,6 +333,7 @@ def exchange(route, ilk = eventing.Ilks.exn dt = date if date is not None else helping.nowIso8601() p = dig if dig is not None else "" + rp = recipient if recipient is not None else "" embeds = embeds if embeds is not None else {} e = dict() @@ -322,26 +349,38 @@ def exchange(route, pather = coring.Pather(path=["e", label]) pathed.extend(pather.qb64b) pathed.extend(atc) - end.extend(coring.Counter(code=coring.CtrDex.PathedMaterialGroup, - count=(len(pathed) // 4)).qb64b) + if len(pathed) // 4 < 4096: + end.extend(coring.Counter(code=coring.CtrDex.PathedMaterialGroup, + count=(len(pathed) // 4)).qb64b) + else: + end.extend(coring.Counter(code=coring.CtrDex.BigPathedMaterialGroup, + count=(len(pathed) // 4)).qb64b) end.extend(pathed) if e: e["d"] = "" _, e = coring.Saider.saidify(sad=e, label=coring.Saids.d) - attrs = dict( - ) + modifiers = modifiers if modifiers is not None else {} + + if diger is None: + attrs = dict() - if recipient is not None: - attrs['i'] = recipient + if recipient is not None: + attrs['i'] = recipient - attrs |= payload + attrs |= payload + + else: + attrs = diger.qb64 + # Attr field 'a' can be either a said or a nested block and the fields + # of the nested block can be saids of further nested block or nested blocks ked = dict(v=vs, t=ilk, d="", i=sender, + rp=rp, p=p, dt=dt, r=route, diff --git a/tests/app/test_delegating.py b/tests/app/test_delegating.py index 132a588c5..f5c83870f 100644 --- a/tests/app/test_delegating.py +++ b/tests/app/test_delegating.py @@ -129,16 +129,16 @@ def test_delegation_request(mockHelpingNowUTC): 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') + b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAACzeUyP' + b'6__0oDca-Oiv2iGXKghBw_8sI4ZHyyeMedvz0iZIIQYqJd2Zt7cDHRh7xBGWI85J' + b'_oOixLET3mFZUu0A') assert exn.ked["r"] == '/delegate/request' - assert exn.saidb == b'EOiDc2wEmhHc7sbLG64y2gveCIRlFe4BuISaz0mlOuZz' + assert exn.saidb == b'EHPkcmdLGql9_1WD0wl0OalYk8PcF4HMMd7gGi-iqfSe' assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAADECnBl' - b'0c14SVi7Keh__sd1PVhinSy-itPr33ZxvSjJYFastqXw9ZTFGNKsY6iALUk5xP3S' - b'399tJrPFe7PtuNAN') + b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAACzeUyP' + b'6__0oDca-Oiv2iGXKghBw_8sI4ZHyyeMedvz0iZIIQYqJd2Zt7cDHRh7xBGWI85J' + b'_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 6d0cbe59e..5fd0090a7 100644 --- a/tests/app/test_grouping.py +++ b/tests/app/test_grouping.py @@ -638,11 +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 exn.saidb == b'EJ6Kl50IBicAa8zND_3wMSQ5itw555V7NKid9y1SKobe' assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAAC84-o2' - b'HKwKxhL1ttzykB9zuFaGV6OpQ05b1ZJYAeBFrR7kVON1aNjpLgQCG_0bY4FUiP7F' - b'GTVDrBjuFhbeDKAH-LAa5AACAA-e-icp-AABAACihaKoLnoXxRoxGbFfOy67YSh6' + b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAACL4cf7' + b'LxzKJgaJbb7wWHLuTfj3wManDV0SW7euFNZDiEhD1kUiP3_wtOIfqB_ZsEceE4oI' + b'gOOZwFROyrcf9ScB-LAa5AACAA-e-icp-AABAACihaKoLnoXxRoxGbFfOy67YSh6' b'UxtgjT2oxupnLDz2FlhevGJKTMObbdex9f0Hqob6uTavSJvsXf5RzitskkkC') data = exn.ked["a"] assert data["smids"] == aids @@ -662,11 +662,11 @@ 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'EAE5RLyDb_3W8fUOzDOHWwpMAvHePaz8Jpz1XWL0b0lQ' + assert exn.saidb == b'EL4LeEHvTiOxs1UDNTv5qWxCYVYojdpEMfKI62O-UsPm' assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAA' - b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAACzqlzb' - b'yRO_M5Kp6nyN1K5JZ9s9D4UAreliSs4OiyCe_y9KnDeP65tub3DW5hUKlVQWnPv4' - b'TrOBHk2vJNOEJtAF') + b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAACH_qI1' + b'JebS_iehZT6XmvxylpOy2hS2BjO41e4mNmscSBdun2MyGk82SC-rHfQfvDJZlRRw' + b'NhLw-pKKKxql8wUF') data = exn.ked["a"] assert data["smids"] == ghab1.smids @@ -681,11 +681,11 @@ def test_multisig_interact(mockHelpingNowUTC): ixn=ixn) assert exn.ked["r"] == '/multisig/ixn' - assert exn.saidb == b'EGQ_DqGlSBx2MKJfHr6liXAngFpQ0UCtV1cdVMUtJHdN' + assert exn.saidb == b'EDF8o6SK-s2jxUVnlGtqAVtXTF-wyZ26c0dUsS5p766q' assert atc == (b'-FABEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba0AAAAAAAAAAAAAAA' - b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAAB3yX6b' - b'EXb8N63PKaMaFqijZVT5TqVtoO8q1BFnoJW3rDkNuJ9lEMpEN-44HKGtvniWZ6-d' - b'CVPS4fsEXKZAKGkB-LAa5AACAA-e-ixn-AABAABG58m7gibjdrQ8YU-8WQ8A70nc' + b'AAAAAAAAEH__mobl7NDyyQCB1DoLK-OPSueraPtZAlWEjfOYkaba-AABAABFfU5s' + b'o86inNogCPN7Ko8WXvkMKeiUKPScQ3FYrVmngNpVmW8xmhOTfixuWFlLcQPjEf3b' + b'RQhvNvx7azcI_vwB-LAa5AACAA-e-ixn-AABAABG58m7gibjdrQ8YU-8WQ8A70nc' b'tYekYr3xdfZ5WgDQOD0bb9pI7SuuaJvzfAQisLAYQnztA82pAo1Skhf1vQwD') data = exn.ked["a"] assert data["smids"] == ghab1.smids @@ -701,11 +701,11 @@ def test_multisig_registry_incept(mockHelpingNowUTC, mockCoringRandomNonce): usage="Issue vLEI Credentials") assert exn.ked["r"] == '/multisig/vcp' - assert exn.saidb == b'EJN27EYqgxTS2NCHdnjE-CU0UikV5a1Cw5OZdv-g0jQ6' + assert exn.saidb == b'EBum6f9SwkUUjQTl_vDplKs7L-shzQT6fS5jJlzdP9PP' assert atc == (b'-FABEDEf72ZZ9mhpT1Xz-_YkXl7cg93sjZUFLIsxaFNTbXQO0AAAAAAAAAAAAAAA' - b'AAAAAAAAEDEf72ZZ9mhpT1Xz-_YkXl7cg93sjZUFLIsxaFNTbXQO-AABAABsPiWf' - b'UE9L7D9KBVOYMg1rt88gK9DBkiBYb21xMR0YH7sCT0hqwX9y8CM5Y6jQwzz3NqqN' - b'-aJWShzz1mbtb5AG-LAa5AACAA-e-anc-AABAABXlwkzbp_tC4MEbx1Uyny1o7dB' + b'AAAAAAAAEDEf72ZZ9mhpT1Xz-_YkXl7cg93sjZUFLIsxaFNTbXQO-AABAAAS5k5D' + b'9jH0rbS6jCtZIPyTJRS2l8TZBnChwG8try3kZUJuiAPoBLo7UuhFYmZlpTZ6MfSg' + b'cDS7XNg0ETj6L3QF-LAa5AACAA-e-anc-AABAABXlwkzbp_tC4MEbx1Uyny1o7dB' b'GHrYjU3u90Mhv2GtrIGG-7va1jZnlXef2R_LM4TRN8_XjmpLv1skcJaM90UB') data = exn.ked["a"] assert data == {'gid': 'EEVG5a8c88Fg9vH-6zQP6gJdc4LxVbUTRydx-JhpDcob', diff --git a/tests/app/test_oobiing.py b/tests/app/test_oobiing.py index 2e81a3050..b9280f7d9 100644 --- a/tests/app/test_oobiing.py +++ b/tests/app/test_oobiing.py @@ -53,19 +53,20 @@ def test_oobi_share(mockHelpingNowUTC): 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', + 'd': 'EII7EvdWFqv0jkjRv10t01zAUcRYbjVhZ_yo3VPZEbpS', 'dt': '2021-01-01T00:00:00.000000+00:00', 'e': {}, 'i': 'EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3', 'p': '', 'q': {}, 'r': '/oobis', + 'rp': '', 't': 'exn', - 'v': 'KERI10JSON00012e_'} + 'v': 'KERI10JSON000136_'} assert atc == (b'-FABEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI30AAAAAAAAAAAAAAA' - b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAACsgmsu' - b'VJoY5a7vicZQ7pT_MZqCe-0psgReRxyoBfFaAPxZ7Vss2eteFuvwDWBeyKc1B-yc' - b'p-2QZzIZJ94_9hIP') + b'AAAAAAAAEIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3-AABAABdw3eS' + b'w_7BW2o3z1ufxxs1CPgX1TgtJzn-MxvMjLYTidUd8KSxNKbPU9M3A4orYJDMGMIz' + b'habHJmKA4ZIGbcgK') def test_oobiery(): diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 0933c0e89..e8eee29b4 100644 --- a/tests/core/test_coring.py +++ b/tests/core/test_coring.py @@ -2179,7 +2179,9 @@ def test_counter(): 'SadPathSigGroups': '-J', 'RootSadPathSigGroups': '-K', 'PathedMaterialGroup': '-L', + 'BigPathedMaterialGroup': '-0L', 'AttachmentGroup': '-V', + 'ESSRPayloadGroup': '-Z', 'BigAttachmentGroup': '-0V', 'KERIACDCGenusVersion': '--AAA', } @@ -2215,7 +2217,9 @@ def test_counter(): '-J': Sizage(hs=2, ss=2, fs=4, ls=0), '-K': Sizage(hs=2, ss=2, fs=4, ls=0), '-L': Sizage(hs=2, ss=2, fs=4, ls=0), + '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), '-V': Sizage(hs=2, ss=2, fs=4, ls=0), + '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0) } @@ -2333,10 +2337,10 @@ def test_counter(): assert counter.qb64 == qsc assert counter.qb2 == qscb2 - # test with big codes index=1024 - count = 1024 + # test with big codes index=1024000 + count = 1024000 qsc = CtrDex.BigAttachmentGroup + intToB64(count, l=5) - assert qsc == '-0VAAAQA' + assert qsc == '-0VAD6AA' qscb = qsc.encode("utf-8") qscb2 = decodeB64(qscb) @@ -2383,6 +2387,42 @@ def test_counter(): test = counter._binfil() assert test == qb2 + # Test limits of PathedMaterialGroup + count = 255 + qsc = CtrDex.PathedMaterialGroup + intToB64(count, l=2) + assert qsc == '-LD_' + qscb = qsc.encode("utf-8") + qscb2 = decodeB64(qscb) + + counter = Counter(code=CtrDex.PathedMaterialGroup, count=count) + assert counter.code == CtrDex.PathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + + counter = Counter(qb64='-L__') + assert counter.count == 4095 + + with pytest.raises(kering.InvalidVarIndexError): + Counter(code=CtrDex.PathedMaterialGroup, count=4096) # Too big + + # Test BigPathedMaterialGroup + # test with big codes index=1024000 + count = 1024000 + qsc = CtrDex.BigPathedMaterialGroup + intToB64(count, l=5) + assert qsc == '-0LAD6AA' + qscb = qsc.encode("utf-8") + qscb2 = decodeB64(qscb) + + counter = Counter(code=CtrDex.BigPathedMaterialGroup, count=count) + assert counter.code == CtrDex.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + + # Test with strip # create code manually count = 1 diff --git a/tests/core/test_counting.py b/tests/core/test_counting.py index 7887a610f..e94d18e5e 100644 --- a/tests/core/test_counting.py +++ b/tests/core/test_counting.py @@ -74,7 +74,9 @@ def test_codexes_tags(): 'SadPathSigGroups': '-J', 'RootSadPathSigGroups': '-K', 'PathedMaterialGroup': '-L', + 'BigPathedMaterialGroup': '-0L', 'AttachmentGroup': '-V', + 'ESSRPayloadGroup': '-Z', 'BigAttachmentGroup': '-0V', 'KERIACDCGenusVersion': '--AAA' } @@ -151,8 +153,10 @@ def test_codexes_tags(): 'SadPathSigGroups': 'SadPathSigGroups', 'RootSadPathSigGroups': 'RootSadPathSigGroups', 'PathedMaterialGroup': 'PathedMaterialGroup', + 'BigPathedMaterialGroup': 'BigPathedMaterialGroup', 'AttachmentGroup': 'AttachmentGroup', 'BigAttachmentGroup': 'BigAttachmentGroup', + 'ESSRPayloadGroup': 'ESSRPayloadGroup', 'KERIACDCGenusVersion': 'KERIACDCGenusVersion' } @@ -353,6 +357,7 @@ def test_counter_class(): '-J': Sizage(hs=2, ss=2, fs=4, ls=0), '-K': Sizage(hs=2, ss=2, fs=4, ls=0), '-L': Sizage(hs=2, ss=2, fs=4, ls=0), + '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), '-V': Sizage(hs=2, ss=2, fs=4, ls=0), '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0) @@ -663,10 +668,10 @@ def test_counter_v1(): assert counter.qb2 == qscb2 assert counter.version == Vrsn_1_0 - # test with big codes index=1024 - count = 1024 + # test with big codes index=100024000 + count = 100024000 qsc = CtrDex.BigAttachmentGroup + intToB64(count, l=5) - assert qsc == '-0VAAAQA' + assert qsc == '-0VF9j7A' qscb = qsc.encode("utf-8") qscb2 = decodeB64(qscb) @@ -723,6 +728,66 @@ def test_counter_v1(): test = counter._binfil() assert test == qb2 + # test BigPathedMaterialGroup with big codes index=100024000 + count = 100024000 + qsc = CtrDex.BigPathedMaterialGroup + intToB64(count, l=5) + assert qsc == '-0LF9j7A' + qscb = qsc.encode("utf-8") + qscb2 = decodeB64(qscb) + + counter = Counter(code=CtrDex.BigPathedMaterialGroup, count=count, gvrsn=Vrsn_1_0) + assert counter.code == CtrDex.BigPathedMaterialGroup + assert counter.tag == AllTags.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + assert counter.version == Vrsn_1_0 + + counter = Counter(qb64b=qscb, gvrsn=Vrsn_1_0) # test with bytes not str + assert counter.code == CtrDex.BigPathedMaterialGroup + assert counter.tag == AllTags.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + assert counter.version == Vrsn_1_0 + + counter = Counter(qb64=qsc, gvrsn=Vrsn_1_0) # test with str not bytes + assert counter.code == CtrDex.BigPathedMaterialGroup + assert counter.tag == AllTags.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + assert counter.version == Vrsn_1_0 + + counter = Counter(qb2=qscb2, gvrsn=Vrsn_1_0) # test with qb2 + assert counter.code == CtrDex.BigPathedMaterialGroup + assert counter.tag == AllTags.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64b == qscb + assert counter.qb64 == qsc + assert counter.qb2 == qscb2 + assert counter.version == Vrsn_1_0 + + # Test ._bexfil + counter = Counter(qb64=qsc, gvrsn=Vrsn_1_0) # + code = counter.code + count = counter.count + qb2 = counter.qb2 + counter._bexfil(qb2) + assert counter.code == code + assert counter.tag == AllTags.BigPathedMaterialGroup + assert counter.count == count + assert counter.qb64 == qsc + assert counter.qb2 == qb2 + assert counter.version == Vrsn_1_0 + + # Test ._binfil + test = counter._binfil() + assert test == qb2 + # Test with strip # create code manually count = 1 diff --git a/tests/core/test_serdering.py b/tests/core/test_serdering.py index 5ca21c30c..ef7cbd07e 100644 --- a/tests/core/test_serdering.py +++ b/tests/core/test_serdering.py @@ -2225,20 +2225,20 @@ 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_', - 't': 'exn', - 'd': 'EMuAoRSE4zREKKYyvuNeYCDM9_MwPQIh1WL0cFC4e-bU', - 'i': '', - 'p': '', - 'dt': '', - 'r': '', - 'q': {}, - '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.sad == {'a': [], + 'd': 'EPx9pShQTfv2FoISZJAZ4dlUcekG8-CSkgJh0i0q_iJn', + 'dt': '', + 'e': {}, + 'i': '', + 'p': '', + 'q': {}, + 'r': '', + 'rp': '', + 't': 'exn', + 'v': 'KERI10JSON000090_'} + + assert serder.raw == (b'{"v":"KERI10JSON000090_","t":"exn","d":"EPx9pShQTfv2FoISZJAZ4dlUcekG8-CSkgJh' + b'0i0q_iJn","i":"","rp":"","p":"","dt":"","r":"","q":{},"a":[],"e":{}}') diff --git a/tests/peer/test_exchanging.py b/tests/peer/test_exchanging.py index 6cb20d739..5e7e96949 100644 --- a/tests/peer/test_exchanging.py +++ b/tests/peer/test_exchanging.py @@ -3,10 +3,15 @@ tests.peer.test_exchanging module """ +import pysodium +from base64 import urlsafe_b64encode as encodeB64 +from base64 import urlsafe_b64decode as decodeB64 + from keri import core -from keri.core import coring, serdering +from keri.core import coring, serdering, MtrDex, parsing from keri.app import habbing, forwarding, storing, signing +from keri.core.coring import CtrDex from keri.peer import exchanging from keri.vdr.eventing import incept @@ -46,6 +51,51 @@ def test_nesting(): assert pathed == {} +def test_essrs(): + with habbing.openHab(name="sid", base="test", salt=b'0123456789abcdef') as (hby, hab), \ + habbing.openHab(name="rec", base="test", salt=b'0123456789abcdef') as (recHby, recHab): + + ims = hab.makeOwnInception() + parsing.Parser().parse(ims=ims, kvy=recHby.kvy) + # create the test message with essr attachment + msg = "This is a test message that must be secured" + rkever = recHab.kever + pubkey = pysodium.crypto_sign_pk_to_box_pk(rkever.verfers[0].raw) + raw = pysodium.crypto_box_seal(msg.encode("utf-8"), pubkey) + + texter = coring.Texter(raw=raw) + diger = coring.Diger(ser=raw, code=MtrDex.Blake3_256) + essr, _ = exchanging.exchange(route='/essr/req', sender=hab.pre, diger=diger, + modifiers=dict(src=hab.pre, dest=recHab.pre)) + ims = hab.endorse(serder=essr, pipelined=False) + ims.extend(coring.Counter(code=CtrDex.ESSRPayloadGroup, count=1).qb64b) + ims.extend(texter.qb64b) + + exc = exchanging.Exchanger(hby=recHby, handlers=[]) + parsing.Parser().parse(ims=ims, kvy=recHby.kvy, exc=exc) + + # Pull the logged exn and verify the attributes digest matches the attachment + serder = recHby.db.exns.get(keys=(essr.said,)) + assert serder.ked['a'] == diger.qb64 + + # Pull the logged ESSR attachment and verify it is the one attached + texter = recHby.db.essrs.get(keys=(serder.said,)) + raw = recHab.decrypt(texter[0].raw) + assert raw.decode("utf-8") == msg + + # Test with invalid diger + diger = coring.Diger(qb64="EKC8085pwSwzLwUGzh-HrEoFDwZnCJq27bVp5atdMT9o") + essr, _ = exchanging.exchange(route='/essr/req', sender=hab.pre, diger=diger, + modifiers=dict(src=hab.pre, dest=recHab.pre)) + ims = hab.endorse(serder=essr, pipelined=False) + ims.extend(coring.Counter(code=CtrDex.ESSRPayloadGroup, count=1).qb64b) + ims.extend(texter[0].qb64b) + + parsing.Parser().parse(ims=ims, kvy=recHby.kvy, exc=exc) + assert recHby.db.exns.get(keys=(essr.said,)) is None + + + def test_exchanger(): with habbing.openHab(name="sid", base="test", salt=b'0123456789abcdef') as (hby, hab), \ habbing.openHab(name="rec", base="test", salt=b'0123456789abcdef') as (recHby, recHab): @@ -101,26 +151,26 @@ 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-Tj4LGHYfFfoVmJJo' + b'09S2gp6ci8rK96upIAKE","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2Q' + b'V8dDjI3","rp":"","p":"","dt":"2021-01-01T00:00:00.000000+00:00",' + b'"r":"/multisig/registry/incept","q":{},"a":{"i":"","m":"Let\'s cr' + b'eate a registry"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp",' + b'"d":"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","i":"EI6hBlgk' + b'WoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","ii":"EIaGMMWJFPmtXznY1IIi' + b'KDIrg-vIyge6mBl2QV8dDjI3","s":"0","c":[],"bt":"0","b":[],"n":"AH' + b'3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10J' + b'SON000138_","t":"ixn","d":"EFuFnevyDFfpWG6il-6Qcv0ne0ZIItLwanCwI' + b'-SU8A9j","i":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","s":' + b'"1","p":"EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3","a":[{"i"' + b':"EI6hBlgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB","s":0,"d":"EI6hB' + b'lgkWoJgkZyfLW35_UyM4nIK44OgsSwFR_WOfvVB"}]},"d":"EL5Nkm6T7HG_0GW' + b'6uwqYSZwlH23khtXvsVE-dq8eO_eE"}}-FABEIaGMMWJFPmtXznY1IIiKDIrg-vI' + b'yge6mBl2QV8dDjI30AAAAAAAAAAAAAAAAAAAAAAAEIaGMMWJFPmtXznY1IIiKDIr' + b'g-vIyge6mBl2QV8dDjI3-AABAAB-teJc_7zot5TAZT6lQi2-GlBzMHXICvt3tIYo' + b'Po2gYXF7PpWDozo3y3wVW9mgHln-1DvQlqn9Aip1YnBgKUQB-LAa5AACAA-e-ixn' + b'-AABAADprTWp4llIzVzBM7VVsDOgXVJdoiVXutsWJEbDJ2pMdjXjNi1xKALBSZ1Z' + b'gRoUsD--LgUQkXIdjLoQ19XPvJMJ') exn = serdering.SerderKERI(raw=msg) @@ -143,27 +193,27 @@ 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-' + b'l3udclHBdOh4OUEqZ33P","i":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVli' + b'I61Bcc2","rp":"","p":"ELkHqph-Tj4LGHYfFfoVmJJo09S2gp6ci8rK96upIA' + b'KE","dt":"2021-01-01T00:00:00.000000+00:00","r":"/multisig/regis' + b'try/incept","q":{},"a":{"i":"","m":"Lets create this registry in' + b'stead"},"e":{"vcp":{"v":"KERI10JSON00010f_","t":"vcp","d":"EB5mt' + b's6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","i":"EB5mts6qrWOZrxjma6' + b'lSTjAdPZ0NSHM1HC3IndbS_giB","ii":"EIREQlatUJODbKogZfa3IqXZ90XdZA' + b'0qJMVliI61Bcc2","s":"0","c":[],"bt":"0","b":[],"n":"AH3-1EZWXU9I' + b'0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"ixn":{"v":"KERI10JSON000138_' + b'","t":"ixn","d":"EOek9JVKNeuW-5UNeHYCTDe70_GtvRwP672oWMNBJpA5","' + b'i":"EIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"1","p":"E' + b'IREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","a":[{"i":"EB5mts6q' + b'rWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","s":0,"d":"EB5mts6qrWOZrxj' + b'ma6lSTjAdPZ0NSHM1HC3IndbS_giB"}]},"d":"EM3gLTzQ9GmKd50Rlm_kiIkeY' + b'kxb004eoOsWahz70TqJ"}}-FABEIREQlatUJODbKogZfa3IqXZ90XdZA0qJMVliI' + b'61Bcc20AAAAAAAAAAAAAAAAAAAAAAAEIREQlatUJODbKogZfa3IqXZ90XdZA0qJM' + b'VliI61Bcc2-AABAADY5nUsBgL23ulcrTgkV09hSzktNHZSlEH1zmVpEggrGgQUq0' + b'tLQeOXztUFDxNQ4Kq2ddIYDVz6d_y0kkU3__YJ-LAa5AACAA-e-ixn-AABAACaox' + b'fQp5L_Gd0nKqJXMbLTXzkrJJDd8RFxWdTSesAMydUzmJQlGt0T9h8L7SwIrq8yBi' + b'nj990PLJHl7sXmq04I') # Test exn from non-transferable AID hab = hby.makeHab(name="test1", transferable=False) @@ -174,18 +224,18 @@ 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-yEv' + b'Xin_-eY1dU4XTCM9ykRC","i":"BJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6-tFV' + b'lCeiZPG","rp":"","p":"","dt":"2021-01-01T00:00:00.000000+00:00",' + b'"r":"/multisig/registry/incept","q":{},"a":{"i":"","m":"Lets cre' + b'ate this registry instead"},"e":{"vcp":{"v":"KERI10JSON00010f_",' + b'"t":"vcp","d":"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","i"' + b':"EB5mts6qrWOZrxjma6lSTjAdPZ0NSHM1HC3IndbS_giB","ii":"EIREQlatUJ' + b'ODbKogZfa3IqXZ90XdZA0qJMVliI61Bcc2","s":"0","c":[],"bt":"0","b":' + b'[],"n":"AH3-1EZWXU9I0fv3Iz_9ZIhjj13JO7u4GNFYC3-l8_K-"},"d":"ENC6' + b'w8wUj-Gp_RpAJN5q4Lf00IHstzNLUvkh3ZvgHGP_"}}-CABBJZ_LF61JTCCSCIw2' + b'Q4ozE2MsbRC4m-N6-tFVlCeiZPG0BB-sQs0WS9wsyuT4hXQD7rbczSfpnQz21wZG' + b'YucRkE0ynKy5draELEKBsckeD0Im1i-kIfMEdbY08YqVfSrEoAA-LAl5AACAA-e-' + b'vcp-CABBJZ_LF61JTCCSCIw2Q4ozE2MsbRC4m-N6-tFVlCeiZPG0BDjOC4j0Co6P' + b'0giMylR47149eJ8Yf_hO-32_TpY77KMVCWCf0U8GuZPIN76R2zsyT_eARvS_zQsX' + b'1ebjl3PMP0D') diff --git a/tests/vc/test_protocoling.py b/tests/vc/test_protocoling.py index f507f9fad..f6dde10bd 100644 --- a/tests/vc/test_protocoling.py +++ b/tests/vc/test_protocoling.py @@ -120,26 +120,26 @@ 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":"EIPeVB3u7L-mEKjhY6zIu5M7LErPwlUccxIN' - b'ddwhcFrH","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","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":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},"e":{}}') + assert apply0.raw == (b'{"v":"KERI10JSON000175_","t":"exn","d":"EHVK5cO32UQJCkpK9RqRP_ONViK8u3JNXn73' + b'nJ8hdmXr","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/apply","q":{},"a":{"m":"P' + b'lease give me a credential","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1k' + b'C","a":{},"i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},"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":"EO4NXvOU-UpwwAR67txzKrFBHGAtDu9ehg8g' - b'Ic5haJy3","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EIPeVB3u7L' - b'-mEKjhY6zIu5M7LErPwlUccxINddwhcFrH","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":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","i":"EMl4Rhu' - b'R_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXe' - b'w8Yo6Z3w9mQUQ","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"' - b'EO9_6NattzsFiO8Fw1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"2021-06-27T21:26:21.2332' - b'57+00:00","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"254900OP' - b'PU84GM83MG36"}},"d":"EOG-KWyllXlb2HVIuewN1YJAOT304PaSczyt3V5Z878S"}}') + assert offer0.raw == (b'{"v":"KERI10JSON0002f8_","t":"exn","d":"ENdVOCsP5Xz57qs1xa_msznozvBs6Ii0_JRo' + b'i6tp2NBu","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EH' + b'VK5cO32UQJCkpK9RqRP_ONViK8u3JNXn73nJ8hdmXr","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/offer","q":{},"a":{"m":"How about this"},"e":{"acdc":{"v"' + b':"ACDC10JSON000197_","d":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","i":' + b'"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VAF7A7_GR8PXJoAVHv' + b'5X9vjtXew8Yo6Z3w9mQUQ","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a' + b'":{"d":"EO9_6NattzsFiO8Fw1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"2021-06-27T21:26' + b':21.233257+00:00","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"' + b'254900OPPU84GM83MG36"}},"d":"EOG-KWyllXlb2HVIuewN1YJAOT304PaSczyt3V5Z878S"}}') # This should fail because it is not first and the apply isn't persisted yet assert ipexhan.verify(serder=offer0) is False @@ -166,26 +166,26 @@ 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":"ENWl0Dd-9idlgrpkFL2aA0wfnuGHzvT4bHCN' - b'G6C0WBZk","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EIPeVB3u7L' - b'-mEKjhY6zIu5M7LErPwlUccxINddwhcFrH","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":"EHijfrof83z7JeFR-wJO9Ptgl-PieQHhKC-F' + b'bZIDvGvM","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EH' + b'VK5cO32UQJCkpK9RqRP_ONViK8u3JNXn73nJ8hdmXr","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/spurn","q":{},"a":{"m":"I reject 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":"ELnRdb-cA_rLckt9jwlSY-1nnPKwzRc4Up_7' - b'tCdzI12n","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","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":"EElymNmgs1u0mSaoC' - b'eOtSsNOROLuqOz103V3-4E-ClXH","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiU' - b'bl","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","s":"EMQWEcCnVRk1hat' - b'TNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EO9_6NattzsFiO8Fw1cxjYmDjOsKKSbootn' - b'-wXn9S3iB","dt":"2021-06-27T21:26:21.233257+00:00","i":"EMl4RhuR_JxpiMd1N8DE' - b'JEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"254900OPPU84GM83MG36"}},"d":"EOG-KWyllXlb2H' - b'VIuewN1YJAOT304PaSczyt3V5Z878S"}}') + assert offer1.raw == (b'{"v":"KERI10JSON0002d5_","t":"exn","d":"EC8fiu3IoCex-7uhTskkEodJOiQYQpO61l3Y' + b'HCXWuuFi","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/offer","q":{},"a":{"m":"H' + b'ere a credential offer"},"e":{"acdc":{"v":"ACDC10JSON000197_","d":"EElymNmgs' + b'1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xy' + b'a8AN-tiUbl","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","s":"EMQWEcC' + b'nVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EO9_6NattzsFiO8Fw1cxjYmDjOs' + b'KKSbootn-wXn9S3iB","dt":"2021-06-27T21:26:21.233257+00:00","i":"EMl4RhuR_Jxp' + b'iMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"254900OPPU84GM83MG36"}},"d":"EOG-KW' + b'yllXlb2HVIuewN1YJAOT304PaSczyt3V5Z878S"}}') # Will work because it is starting a new conversation assert ipexhan.verify(serder=offer1) is True @@ -197,10 +197,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":"EEtu1OAPj03IdbhMwsQtgbJJaWgG2tdYLJ_3' - b'BuJQekdP","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EO4NXvOU-U' - b'pwwAR67txzKrFBHGAtDu9ehg8gIc5haJy3","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":"ECU3UjnSY1_6Wl3aYEW19jaGiKuyFh_chIQQ' + b'w48bcT_X","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EN' + b'dVOCsP5Xz57qs1xa_msznozvBs6Ii0_JRoi6tp2NBu","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/agree","q":{},"a":{"m":"I\'ll accept that offer"},"e":' + b'{}}') # 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 @@ -215,24 +216,24 @@ 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":"EC-EsfvXD2cNw4GNgCFp9UTl7_DgWUgk9Rnw' - b'eCxocaG-","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"","dt":"20' - b'21-06-27T21:26:21.233257+00:00","r":"/ipex/grant","q":{},"a":{"m":"Here\'' - b's a credential","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},"e":{"ac' - b'dc":{"v":"ACDC10JSON000197_","d":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-Cl' - b'XH","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VAF7A7_GR8' - b'PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gk' - b'k1kC","a":{"d":"EO9_6NattzsFiO8Fw1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"2021-06-' - b'27T21:26:21.233257+00:00","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"' - b',"LEI":"254900OPPU84GM83MG36"}},"iss":{"v":"KERI10JSON0000ed_","t":"iss","d"' - b':"ECUw7AdWEE3fvr7dgbFDXj0CEZuJTTa_H8-iLLAmIUPO","i":"EElymNmgs1u0mSaoCeOtSsN' - b'OROLuqOz103V3-4E-ClXH","s":"0","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w' - b'9mQUQ","dt":"2021-06-27T21:26:21.233257+00:00"},"anc":{"v":"KERI10JSON00013a' - b'_","t":"ixn","d":"EGhSHKIV5-nkeirdkqzqsvmeF1FXw_yH8NvPSAY1Rgyd","i":"EMl4Rhu' - b'R_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","s":"2","p":"ED1kkh5_ECYriK-j2gSv6Zjr' - b'5way88XVhwRCxk5zoTRG","a":[{"i":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClX' - b'H","s":"0","d":"ECUw7AdWEE3fvr7dgbFDXj0CEZuJTTa_H8-iLLAmIUPO"}]},"d":"EJ4-dl' - b'S9ktlb9HDWPYc0IJ2hS2NbvnCQBhUsFSkEPwIo"}}') + assert grant0.raw == (b'{"v":"KERI10JSON000539_","t":"exn","d":"ELnjKvzdgO57JZwG3giIScoOeTB0rLuevniv' + b'zRE5DbTE","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"",' + b'"dt":"2021-06-27T21:26:21.233257+00:00","r":"/ipex/grant","q":{},"a":{"m":"H' + b'ere\'s a credential","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},' + b'"e":{"acdc":{"v":"ACDC10JSON000197_","d":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103' + b'V3-4E-ClXH","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VA' + b'F7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvaf' + b'X3bHQ9Gkk1kC","a":{"d":"EO9_6NattzsFiO8Fw1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"' + b'2021-06-27T21:26:21.233257+00:00","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8A' + b'N-tiUbl","LEI":"254900OPPU84GM83MG36"}},"iss":{"v":"KERI10JSON0000ed_","t":"' + b'iss","d":"ECUw7AdWEE3fvr7dgbFDXj0CEZuJTTa_H8-iLLAmIUPO","i":"EElymNmgs1u0mSa' + b'oCeOtSsNOROLuqOz103V3-4E-ClXH","s":"0","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXe' + b'w8Yo6Z3w9mQUQ","dt":"2021-06-27T21:26:21.233257+00:00"},"anc":{"v":"KERI10JS' + b'ON00013a_","t":"ixn","d":"EGhSHKIV5-nkeirdkqzqsvmeF1FXw_yH8NvPSAY1Rgyd","i":' + b'"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","s":"2","p":"ED1kkh5_ECYriK-j' + b'2gSv6Zjr5way88XVhwRCxk5zoTRG","a":[{"i":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V' + b'3-4E-ClXH","s":"0","d":"ECUw7AdWEE3fvr7dgbFDXj0CEZuJTTa_H8-iLLAmIUPO"}]},"d"' + b':"EJ4-dlS9ktlb9HDWPYc0IJ2hS2NbvnCQBhUsFSkEPwIo"}}') assert ipexhan.verify(serder=grant0) is True @@ -245,10 +246,10 @@ 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":"EJA0LVnMxOdrOEArWudVtdonorCUa4nCIRgX' - b'vibhxdp3","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EC-EsfvXD2' - b'cNw4GNgCFp9UTl7_DgWUgk9RnweCxocaG-","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":"ELHFilyCgYvVq6vczgPQc7ZuRMs7Cv10U_h-' + b'2LIvJ1-Z","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EL' + b'njKvzdgO57JZwG3giIScoOeTB0rLuevnivzRE5DbTE","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/spurn","q":{},"a":{"m":"I reject you"},"e":{}}') smsg = bytearray(spurn1.raw) smsg.extend(spurn1atc) parsing.Parser().parse(ims=smsg, exc=sidExc) @@ -258,25 +259,25 @@ 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":"EBAhSTTx3--xDZZRoCIemBzxybFV_FoicvPf' - b'4hSfeyAJ","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EEtu1OAPj0' - b'3IdbhMwsQtgbJJaWgG2tdYLJ_3BuJQekdP","dt":"2021-06-27T21:26:21.233257+00:00",' - b'"r":"/ipex/grant","q":{},"a":{"m":"Here\'s a credential","i":"EMl4RhuR_Jx' - b'piMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},"e":{"acdc":{"v":"ACDC10JSON000197_","d"' - b':"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","i":"EMl4RhuR_JxpiMd1N8DEJEh' - b'TxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","' - b's":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EO9_6NattzsFiO8F' - b'w1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"2021-06-27T21:26:21.233257+00:00","i":"E' - b'Ml4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"254900OPPU84GM83MG36"}},' - b'"iss":{"v":"KERI10JSON0000ed_","t":"iss","d":"ECUw7AdWEE3fvr7dgbFDXj0CEZuJTT' - b'a_H8-iLLAmIUPO","i":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","s":"0","' - b'ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","dt":"2021-06-27T21:26:21' - b'.233257+00:00"},"anc":{"v":"KERI10JSON00013a_","t":"ixn","d":"EGhSHKIV5-nkei' - b'rdkqzqsvmeF1FXw_yH8NvPSAY1Rgyd","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-' - b'tiUbl","s":"2","p":"ED1kkh5_ECYriK-j2gSv6Zjr5way88XVhwRCxk5zoTRG","a":[{"i":' - b'"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","s":"0","d":"ECUw7AdWEE3fvr7d' - b'gbFDXj0CEZuJTTa_H8-iLLAmIUPO"}]},"d":"EJ4-dlS9ktlb9HDWPYc0IJ2hS2NbvnCQBhUsFS' - b'kEPwIo"}}') + assert grant1.raw == (b'{"v":"KERI10JSON000565_","t":"exn","d":"EHAY_L6Ig4k_5qIw6uH-QZwBswWLfwVzCqaG' + b'sjtdnubK","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EC' + b'U3UjnSY1_6Wl3aYEW19jaGiKuyFh_chIQQw48bcT_X","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/grant","q":{},"a":{"m":"Here\'s a credential","i":"EMl' + b'4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl"},"e":{"acdc":{"v":"ACDC10JSON0001' + b'97_","d":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","i":"EMl4RhuR_JxpiMd' + b'1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w' + b'9mQUQ","s":"EMQWEcCnVRk1hatTNyK3sIykYSrrFvafX3bHQ9Gkk1kC","a":{"d":"EO9_6Nat' + b'tzsFiO8Fw1cxjYmDjOsKKSbootn-wXn9S3iB","dt":"2021-06-27T21:26:21.233257+00:00' + b'","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","LEI":"254900OPPU84GM83' + b'MG36"}},"iss":{"v":"KERI10JSON0000ed_","t":"iss","d":"ECUw7AdWEE3fvr7dgbFDXj' + b'0CEZuJTTa_H8-iLLAmIUPO","i":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","' + b's":"0","ri":"EB-u4VAF7A7_GR8PXJoAVHv5X9vjtXew8Yo6Z3w9mQUQ","dt":"2021-06-27T' + b'21:26:21.233257+00:00"},"anc":{"v":"KERI10JSON00013a_","t":"ixn","d":"EGhSHK' + b'IV5-nkeirdkqzqsvmeF1FXw_yH8NvPSAY1Rgyd","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn' + b'9Xya8AN-tiUbl","s":"2","p":"ED1kkh5_ECYriK-j2gSv6Zjr5way88XVhwRCxk5zoTRG","a' + b'":[{"i":"EElymNmgs1u0mSaoCeOtSsNOROLuqOz103V3-4E-ClXH","s":"0","d":"ECUw7AdW' + b'EE3fvr7dgbFDXj0CEZuJTTa_H8-iLLAmIUPO"}]},"d":"EJ4-dlS9ktlb9HDWPYc0IJ2hS2Nbvn' + b'CQBhUsFSkEPwIo"}}') assert ipexhan.verify(serder=grant1) is True gmsg = bytearray(grant1.raw) @@ -287,10 +288,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":"EDkQZpUOKKOzsQ50yoZxzLz8tDaChAid_llr' - b'QNvKVAdO","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","p":"EBAhSTTx3-' - b'-xDZZRoCIemBzxybFV_FoicvPf4hSfeyAJ","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":"EMxU5rfeqKnZzrbqnL7weXQGaC8Zum4qowj2' + b'eiL6GxqL","i":"EMl4RhuR_JxpiMd1N8DEJEhTxM3Ovvn9Xya8AN-tiUbl","rp":"","p":"EH' + b'AY_L6Ig4k_5qIw6uH-QZwBswWLfwVzCqaGsjtdnubK","dt":"2021-06-27T21:26:21.233257' + b'+00:00","r":"/ipex/admit","q":{},"a":{"m":"Thanks for the credential"},"e":{' + b'}}') assert ipexhan.verify(serder=admit0) is True amsg = bytearray(admit0.raw)