Beispiel #1
0
def backer_revoke(
    vcdig,
    regk,
    regsn,
    regd,
    version=Version,
    kind=Serials.json,
):
    """

    Returns serder of brv message event
    Utility function to create a VC revocation event

    Parameters:
        vcdig is hash digest of vc content qb64
        regk is regsitry identifier prefix qb64
        regsn is int sequence number of anchoring registry TEL event
        regd is digest qb64 of anchoring registry TEL event
    """

    vs = Versify(version=version, kind=kind, size=0)
    isn = 1
    ilk = Ilks.rev

    seal = SealEvent(regk, regsn, regd)

    ked = dict(
        v=vs,
        i=vcdig,
        s="{:x}".format(isn),  # hex string no leading zeros lowercase
        t=ilk,
        ra=seal._asdict())

    return Serder(ked=ked)  # return serialized ked
Beispiel #2
0
    def __init__(self, hab, name="test", reg=None, allowBackers=True, baks=None, toad=None,
                 estOnly=False):
        """
        Initialize Instance

        Parameters:
            name is the alias for this issuer
            hab is Habitat instance of local controller's context
            reg is Registry instance for controller's credentials
            allowBackers is boolean True to allow specification of TEL specific backers
            backers is the initial list of backer prefixes qb64 for VCs in the Registry
            toad is int or str hex of witness threshold
            estOnly is boolean True for forcing rotation events for every TEL event.
        """

        self.estOnly = estOnly
        self.allowBackers = allowBackers
        self.hab = hab
        self.name = name
        self.regi = 0
        self.vcser = None

        self.reg = reg if reg is not None else Registry(name=name)

        # save backers locally for now.  will be managed by tever when implemented
        self.backers = baks if baks is not None else []

        self.cnfg = [] if self.allowBackers else [TraitDex.NoBackers]

        self.regser = eventing.incept(self.hab.pre,
                                      baks=self.backers,
                                      toad=toad,
                                      cnfg=self.cnfg,
                                      code=MtrDex.Blake3_256)
        self.regk = self.regser.pre

        rseal = SealEvent(self.regk, self.regser.ked["s"], self.regser.diger.qb64)

        if self.estOnly:
            self.ianchor = self.hab.rotate(data=rseal)
        else:
            self.ianchor = self.hab.interact(data=rseal)

        seal = SealEvent(i=self.hab.pre, s=self.hab.kever.sn, d=self.hab.kever.serder.dig)

        msg = self.messagize(serder=self.regser, seal=seal)

        # Process message in local Tevery when ready for now assign to self for testing
        self.incept = msg
Beispiel #3
0
    def rotate(self, toad=None, cuts=None, adds=None):
        """
        Rotate backer list for registry

        Parameters:
            toad is int or str hex of backer threshold after cuts and adds
            cuts is list of qb64 pre of backers to be removed from witness list
            adds is list of qb64 pre of backers to be added to witness list
        """

        if not self.allowBackers:
            raise ValueError("Attempt to rotate registry {} that does not support backers".format(self.regk))

        serder = eventing.rotate(dig=self.regser.dig, regk=self.regk, sn=self.regi+1, toad=toad, baks=self.backers,
                                 adds=adds, cuts=cuts)

        self.regser = serder
        rseal = SealEvent(self.regk, serder.ked["s"], self.regser.diger.qb64)

        tevt, kevt = self.anchorMsg(serder, rseal)

        # Process message in local Tevery when ready
        self.regi += 1

        return tevt, kevt
Beispiel #4
0
    def anchorMsg(self, serder, rseal):
        if self.estOnly:
            kevt = self.hab.rotate(data=rseal)
        else:
            kevt = self.hab.interact(data=rseal)

        seal = SealEvent(i=self.hab.pre, s=self.hab.kever.sn, d=self.hab.kever.serder.dig)
        tevt = self.messagize(serder=serder, seal=seal)

        return tevt, kevt
Beispiel #5
0
    def issue(self, vcdig):
        """

        Create and process an iss or bis message event

        Parameters:
            vcdig is hash digest of vc content qb64

        """

        if self.allowBackers:
            serder = eventing.backer_issue(vcdig=vcdig, regk=self.regk, regsn=self.regi, regd=self.regser.diger.qb64)
        else:
            serder = eventing.issue(vcdig=vcdig, regk=self.regk)

        self.vcser = serder
        rseal = SealEvent(vcdig, self.vcser.ked["s"], self.vcser.diger.qb64)

        msg, kevt = self.anchorMsg(serder, rseal)

        # Process message in local Tevery when ready
        return msg, kevt
Beispiel #6
0
def test_direct_mode_with_manager():
    """
    Test direct mode with transferable validator event receipts

    """
    # manual process to generate a list of secrets
    # root = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES)
    # secrets = generateSecrets(root=root, count=8)

    # Direct Mode initiated by coe is controller, val is validator
    # but goes both ways once initiated.

    # set of secrets  (seeds for private keys)
    coeSalt = Salter(raw=b'0123456789abcdea').qb64

    # set of secrets (seeds for private keys)
    valSalt = Salter(raw=b'1123456789abcdea').qb64


    with openDB("controller") as coeLogger, openDB("validator") as valLogger, \
         openKS(name="controller") as coeKpr, openKS(name="validator") as valKpr:
        # Init key pair manager
        coeMgr = Manager(keeper=coeKpr, salt=coeSalt)
        coeVerfers, coeDigers, cst, nst = coeMgr.incept(icount=1, ncount=1)

        #  init Keverys
        coeKevery = eventing.Kevery(db=coeLogger)
        valKevery = eventing.Kevery(db=valLogger)

        coe_event_digs = []  # list of controller's own event log digs to verify against database
        val_event_digs = []  # list of validator's own event log digs to verify against database

        #  init sequence numbers for both controller and validator
        csn = cesn = 0  # sn and last establishment sn = esn
        vsn = vesn = 0  # sn and last establishment sn = esn

        # Controller Event 0  Inception Transferable (nxt digest not empty)
        coeSerder = incept(keys=[coeVerfers[0].qb64],
                           nxt=eventing.Nexter(digs=[coeDigers[0].qb64]).qb64,
                           code=MtrDex.Blake3_256)

        assert csn == int(coeSerder.ked["s"], 16) == 0
        coepre = coeSerder.ked["i"]

        coe_event_digs.append(coeSerder.dig)
        # sign serialization
        sigers = coeMgr.sign(ser=coeSerder.raw, verfers=coeVerfers)

        #  create serialized message
        cmsg = messagize(coeSerder, sigers=sigers)

        # create own Controller Kever in  Controller's Kevery
        parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery)
        # coeKevery.processOne(ims=bytearray(cmsg))  # send copy of cmsg
        coeKever = coeKevery.kevers[coepre]
        assert coeKever.prefixer.qb64 == coepre

        # Validator Event 0  Inception Transferable (nxt digest not empty)
        # Init key pair manager
        valMgr = Manager(keeper=valKpr, salt=valSalt)
        valVerfers, valDigers, cst, nst = valMgr.incept(icount=1, ncount=1)

        valSerder = incept(keys=[valVerfers[0].qb64],
                           nxt=eventing.Nexter(digs=[valDigers[0].qb64]).qb64,
                           code=MtrDex.Blake3_256)

        assert vsn == int(valSerder.ked["s"], 16) == 0
        valpre = valSerder.ked["i"]

        val_event_digs.append(valSerder.dig)

        # sign serialization
        sigers = valMgr.sign(valSerder.raw, verfers=valVerfers)  # return Siger if index

        #  create serialized message
        vmsg = messagize(valSerder, sigers=sigers)

        # create own Validator Kever in  Validator's Kevery
        parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery)
        # valKevery.processOne(ims=bytearray(vmsg))  # send copy of vmsg
        valKever = valKevery.kevers[valpre]
        assert valKever.prefixer.qb64 == valpre

        # simulate sending of controller's inception message to validator
        parsing.Parser().parse(ims=bytearray(cmsg), kvy=valKevery)
        # valKevery.process(ims=bytearray(cmsg))  # make copy of msg
        assert coepre in valKevery.kevers  # creates Kever for controller in validator's .kevers

        # create receipt of controller's inception
        # create seal of validator's last establishment event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        coeK = valKevery.kevers[coepre]  # lookup coeKever from validator's .kevers
        # create trans receipt
        reserder = receipt(pre=coeK.prefixer.qb64,
                           sn=coeK.sn,
                           dig=coeK.serder.diger.qb64)
        #reserder = chit(pre=coeK.prefixer.qb64,
                        #sn=coeK.sn,
                        #dig=coeK.serder.diger.qb64,
                        #seal=seal)
        # Validate receipt

        # sign controller's event not receipt
        # look up event to sign from validator's kever for coe
        coeIcpDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeIcpDig == coeK.serder.diger.qb64b
        coeIcpRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIcpDig)))

        #counter = Counter(CtrDex.ControllerIdxSigs)
        #assert counter.qb64 == '-AAB'
        sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers)  # return Siger if index

        # process own validator receipt in validator's Kevery so have copy in own log
        rmsg = messagize(reserder, sigers=sigers, seal=seal)
        assert len(rmsg) == 353

        parsing.Parser().parseOne(ims=bytearray(rmsg), kvy=valKevery)
        # valKevery.processOne(ims=bytearray(rmsg))  # process copy of rmsg

        # attach receipt message to existing message with validators inception message
        # simulate streaming. validator first sends it's inception event, then sends a receipt to controller
        vmsg.extend(rmsg)

        # Simulate sending validator's inception event and receipt of
        # controller's inception message to controller
        parsing.Parser().parse(ims=vmsg, kvy=coeKevery)
        # coeKevery.process(ims=vmsg)  # controller process validator's inception and receipt

        # check if validator's Kever in controller's .kevers
        assert valpre in coeKevery.kevers
        #  check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)


        # create receipt to escrow use invalid digest and sequence number so not in controller's db
        fake = reserder.dig  # some other digest
        reserder = receipt(pre=coeK.prefixer.qb64,
                        sn=10,
                        dig=fake)
        # sign event not receipt
        sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers)  # return Siger if index
        # create receipt message
        vmsg = messagize(reserder, sigers=sigers, seal=seal)

        parsing.Parser().parse(ims=bytearray(vmsg), kvy=coeKevery)
        # coeKevery.process(ims=vmsg)  # controller process the escrow receipt from validator
        #  check if receipt quadruple in escrow database
        result = coeKevery.db.getVres(key=snKey(pre=coeKever.prefixer.qb64,
                                                   sn=10))
        assert bytes(result[0]) == (fake.encode("utf-8") +
                                    valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        # Send receipt from controller to validator
        # create receipt of validator's inception
        # create seal of controller's last establishment event
        seal = SealEvent(i=coepre,
                         s="{:x}".format(coeKever.lastEst.s),
                         d=coeKever.lastEst.d)
        valK = coeKevery.kevers[valpre]  # lookup valKever from controller's .kevers
        # create trans receipt
        reserder = receipt(pre=valK.prefixer.qb64,
                        sn=valK.sn,
                        dig=valK.serder.diger.qb64,)
        # sign validator's event not receipt
        # look up event to sign from controller's kever for validator
        valIcpDig = bytes(coeKevery.db.getKeLast(key=snKey(pre=valpre, sn=vsn)))
        assert valIcpDig == valK.serder.diger.qb64b
        valIcpRaw = bytes(coeKevery.db.getEvt(key=dgKey(pre=valpre, dig=valIcpDig)))
        sigers = coeMgr.sign(ser=valIcpRaw, verfers=coeVerfers)  # return Siger if index
        # create receipt message
        cmsg = messagize(reserder, sigers=sigers, seal=seal)
        # controller process own receipt in own Kevery so have copy in own log
        parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery)
        # coeKevery.processOne(ims=bytearray(cmsg))  # make copy

        # Simulate sending controller's receipt of validator's inception message to validator
        parsing.Parser().parse(ims=cmsg, kvy=valKevery)
        # valKevery.process(ims=cmsg)  # controller process validator's inception and receipt

        #  check if receipt quadruple from controller in validator's receipt database
        result = valKevery.db.getVrcs(key=dgKey(pre=valKever.prefixer.qb64,
                                                   dig=valKever.serder.diger.qb64))
        assert bytes(result[0]) == (coeKever.prefixer.qb64b +
                                    Seqner(sn=coeKever.sn).qb64b +
                                    coeKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        # Controller Event 1 Rotation Transferable
        csn += 1
        cesn += 1
        assert csn == cesn == 1
        coeVerfers, coeDigers, cst, nst = coeMgr.rotate(pre=coeVerfers[0].qb64)
        coeSerder = rotate(pre=coeKever.prefixer.qb64,
                           keys=[coeVerfers[0].qb64],
                           dig=coeKever.serder.diger.qb64,
                           nxt=eventing.Nexter(digs=[coeDigers[0].qb64]).qb64,
                           sn=csn)
        coe_event_digs.append(coeSerder.dig)

        # sign serialization
        sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers)  # returns sigers

        #  create serialized message
        cmsg = messagize(coeSerder, sigers=sigers)

        # update controller's key event verifier state
        parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery)
        # coeKevery.processOne(ims=bytearray(cmsg))  # make copy
        # verify controller's copy of controller's event stream is updated
        assert coeKever.sn == csn
        assert coeKever.serder.diger.qb64 == coeSerder.dig

        # simulate send message from controller to validator
        parsing.Parser().parse(ims=cmsg, kvy=valKevery)
        # valKevery.process(ims=cmsg)
        # verify validator's copy of controller's event stream is updated
        assert coeK.sn == csn
        assert coeK.serder.diger.qb64 == coeSerder.dig

        # create receipt of controller's rotation
        # create seal of validator's last establishment event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        # create validator receipt
        reserder = receipt(pre=coeK.prefixer.qb64,
                           sn=coeK.sn,
                           dig=coeK.serder.diger.qb64)
        # sign controller's event not receipt
        # look up event to sign from validator's kever for controller
        coeRotDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeRotDig == coeK.serder.diger.qb64b
        coeRotRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeRotDig)))
        sigers = valMgr.sign(ser=coeRotRaw, verfers=valVerfers)
        # validator create receipt message
        vmsg = messagize(reserder, sigers=sigers, seal=seal)

        # validator process own receipt in own kevery so have copy in own log
        parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery)
        # valKevery.processOne(ims=bytearray(vmsg))  # make copy

        # Simulate send to controller of validator's receipt of controller's rotation message
        parsing.Parser().parse(ims=vmsg, kvy=coeKevery)
        # coeKevery.process(ims=vmsg)  # controller process validator's incept and receipt

        # check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        # Next Event 2 Controller Interaction
        csn += 1  # do not increment esn
        assert csn == 2
        assert cesn == 1
        coeSerder = interact(pre=coeKever.prefixer.qb64,
                             dig=coeKever.serder.diger.qb64,
                             sn=csn)
        coe_event_digs.append(coeSerder.dig)

        # sign serialization
        sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers)

        # create msg
        cmsg = messagize(coeSerder, sigers=sigers)

        # update controller's key event verifier state
        parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery)
        # coeKevery.processOne(ims=bytearray(cmsg))  # make copy
        # verify controller's copy of controller's event stream is updated
        assert coeKever.sn == csn
        assert coeKever.serder.diger.qb64 == coeSerder.dig

        # simulate send message from controller to validator
        parsing.Parser().parse(ims=cmsg, kvy=valKevery)
        # valKevery.process(ims=cmsg)
        # verify validator's copy of controller's event stream is updated
        assert coeK.sn == csn
        assert coeK.serder.diger.qb64 == coeSerder.dig

        # create receipt of controller's interaction
        # create seal of validator's last est event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        # create validator receipt
        reserder = receipt(pre=coeK.prefixer.qb64,
                        sn=coeK.sn,
                        dig=coeK.serder.diger.qb64)
        # sign controller's event not receipt
        # look up event to sign from validator's kever for controller
        coeIxnDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeIxnDig == coeK.serder.diger.qb64b
        coeIxnRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIxnDig)))
        sigers = valMgr.sign(ser=coeIxnRaw, verfers=valVerfers)
        # create receipt message
        vmsg = messagize(reserder, sigers=sigers, seal=seal)

        # validator process own receipt in own kevery so have copy in own log
        parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery)
        # valKevery.processOne(ims=bytearray(vmsg))  # make copy

        # Simulate send to controller of validator's receipt of controller's rotation message
        parsing.Parser().parse(ims=bytearray(vmsg), kvy=coeKevery)
        # coeKevery.process(ims=vmsg)  # controller process validator's incept and receipt

        #  check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)


        #  verify final controller event state
        assert coeKever.sn == coeK.sn == csn

        db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(coepre)]
        assert len(db_digs) == len(coe_event_digs) == csn + 1
        assert db_digs == coe_event_digs

        db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(coepre)]
        assert len(db_digs) == len(coe_event_digs) == csn + 1
        assert db_digs == coe_event_digs

        #  verify final validator event state
        assert valKever.sn == valK.sn == vsn

        db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(valpre)]
        assert len(db_digs) == len(val_event_digs) == vsn + 1
        assert db_digs == val_event_digs

        db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(valpre)]
        assert len(db_digs) == len(val_event_digs) == vsn + 1
        assert db_digs == val_event_digs

    assert not os.path.exists(valKevery.db.path)
    assert not os.path.exists(coeKever.baser.path)
Beispiel #7
0
def test_direct_mode_with_manager():
    """
    Test direct mode with transferable validator event receipts

    """
    # manual process to generate a list of secrets
    # root = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES)
    # secrets = generateSecrets(root=root, count=8)

    # Direct Mode initiated by coe is controller, val is validator
    # but goes both ways once initiated.

    # set of secrets  (seeds for private keys)
    coeSalt = Salter(raw=b'0123456789abcdea').qb64

    # set of secrets (seeds for private keys)
    valSalt = Salter(raw=b'1123456789abcdea').qb64


    with openDB("controller") as coeLogger, openDB("validator") as valLogger, openKS(name="controller") as coeKpr, openKS(name="validator") as valKpr:
        # Init key pair manager
        coeMgr = Manager(keeper=coeKpr, salt=coeSalt)
        coeVerfers, coeDigers = coeMgr.incept(icount=1, ncount=1)

        #  init Keverys
        coeKevery = Kevery(db=coeLogger)
        valKevery = Kevery(db=valLogger)

        coe_event_digs = []  # list of controller's own event log digs to verify against database
        val_event_digs = []  # list of validator's own event log digs to verify against database

        #  init sequence numbers for both controller and validator
        csn = cesn = 0  # sn and last establishment sn = esn
        vsn = vesn = 0  # sn and last establishment sn = esn

        # Controller Event 0  Inception Transferable (nxt digest not empty)
        coeSerder = incept(keys=[coeVerfers[0].qb64],
                           nxt=Nexter(digs=[coeDigers[0].qb64]).qb64,
                           code=MtrDex.Blake3_256)

        assert csn == int(coeSerder.ked["s"], 16) == 0
        coepre = coeSerder.ked["i"]
        assert coepre == 'EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas'

        coe_event_digs.append(coeSerder.dig)
        # sign serialization
        sigers = coeMgr.sign(ser=coeSerder.raw, verfers=coeVerfers)

        #  create serialized message
        cmsg = messagize(coeSerder, sigers)
        assert cmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"0","t":"icp","kt":"1","k":["Dpt7mGZ3y5UmhT1NLEx'
                                 b'b1IW8vMJ8ylQW3K44LfkTgAqE"],"n":"Erpltchg7BUv21Qz3ZXhOhVu63m7S7Y'
                                 b'bPb21lSeGYd90","wt":"0","w":[],"c":[]}-AABAA2dW-FXhcUiGQZh1JhRrh'
                                 b'_JDqEPU678KT0U8F_a-l8Q3sO25xJAs3Iu2bBonBPZjVo_Zc8FVqrqXjQxxUPt4ICg')

        # create own Controller Kever in  Controller's Kevery
        coeKevery.processOne(ims=bytearray(cmsg))  # send copy of cmsg
        coeKever = coeKevery.kevers[coepre]
        assert coeKever.prefixer.qb64 == coepre

        # Validator Event 0  Inception Transferable (nxt digest not empty)
        # Init key pair manager
        valMgr = Manager(keeper=valKpr, salt=valSalt)
        valVerfers, valDigers = valMgr.incept(icount=1, ncount=1)

        valSerder = incept(keys=[valVerfers[0].qb64],
                           nxt=Nexter(digs=[valDigers[0].qb64]).qb64,
                           code=MtrDex.Blake3_256)

        assert vsn == int(valSerder.ked["s"], 16) == 0
        valpre = valSerder.ked["i"]
        assert valpre == 'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0'

        val_event_digs.append(valSerder.dig)

        # sign serialization
        sigers = valMgr.sign(valSerder.raw, verfers=valVerfers)  # return Siger if index

        #  create serialized message
        vmsg = messagize(valSerder, sigers)
        assert vmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF'
                                 b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA'
                                 b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl'
                                 b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}-AABAAxvl1581mKQME95XZrjsy'
                                 b'CXxJ3fCnmNSG_Bc1I4FcxEoeQbgdLAQ8sudwb0FHOYXfqRE6Z7PraaU82YQDyVShDw')

        # create own Validator Kever in  Validator's Kevery
        valKevery.processOne(ims=bytearray(vmsg))  # send copy of vmsg
        valKever = valKevery.kevers[valpre]
        assert valKever.prefixer.qb64 == valpre

        # simulate sending of controller's inception message to validator
        valKevery.process(ims=bytearray(cmsg))  # make copy of msg
        assert coepre in valKevery.kevers  # creates Kever for controller in validator's .kevers

        # create receipt of controller's inception
        # create seal of validator's last establishment event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        coeK = valKevery.kevers[coepre]  # lookup coeKever from validator's .kevers
        # create validator receipt
        reserder = chit(pre=coeK.prefixer.qb64,
                        sn=coeK.sn,
                        dig=coeK.serder.diger.qb64,
                        seal=seal)
        # Validate receipt
        assert reserder.raw == (b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",'
                                b'"s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","a":{"i'
                                b'":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7x'
                                b'HnuE-wyiarIZ9j-1CEQ89I0E3WevcE"}}')

        # sign controller's event not receipt
        # look up event to sign from validator's kever for coe
        coeIcpDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeIcpDig == coeK.serder.diger.qb64b == b'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc'
        coeIcpRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIcpDig)))
        assert coeIcpRaw == (b'{"v":"KERI10JSON0000e6_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",'
                             b'"s":"0","t":"icp","kt":"1","k":["Dpt7mGZ3y5UmhT1NLExb1IW8vMJ8ylQW3K44LfkTgAq'
                             b'E"],"n":"Erpltchg7BUv21Qz3ZXhOhVu63m7S7YbPb21lSeGYd90","wt":"0","w":[],"c":['
                             b']}')
        counter = Counter(CtrDex.ControllerIdxSigs)
        assert counter.qb64 == '-AAB'
        sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers)  # return Siger if index

        # process own validator receipt in validator's Kevery so have copy in own log
        rmsg = messagize(reserder, sigers)
        assert rmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",'
                                 b'"s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","a":{"i'
                                 b'":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7x'
                                 b'HnuE-wyiarIZ9j-1CEQ89I0E3WevcE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwy'
                                 b'qst_ZvLo05jau9GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA')

        valKevery.processOne(ims=bytearray(rmsg))  # process copy of rmsg

        # attach receipt message to existing message with validators inception message
        # simulate streaming. validator first sends it's inception event, then sends a receipt to controller
        vmsg.extend(rmsg)
        assert vmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF'
                                 b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA'
                                 b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl'
                                 b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}-AABAAxvl1581mKQME95XZrjsy'
                                 b'CXxJ3fCnmNSG_Bc1I4FcxEoeQbgdLAQ8sudwb0FHOYXfqRE6Z7PraaU82YQDyVSh'
                                 b'Dw{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14Vk'
                                 b'BOCJnPYabcas","s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us'
                                 b'-0juFL5hOAHAwIEkc","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFB'
                                 b'DyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3W'
                                 b'evcE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyqst_ZvLo05jau9'
                                 b'GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA')

        # Simulate sending validator's inception event and receipt of controller's inception message to controller
        coeKevery.process(ims=vmsg)  # controller process validator's inception and receipt

        # check if validator's Kever in controller's .kevers
        assert valpre in coeKevery.kevers
        #  check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ'
                                    b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyq'
                                    b'st_ZvLo05jau9GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA')

        # create receipt to escrow use invalid digest and sequence number so not in controller's db
        fake = reserder.dig  # some other digest
        reserder = chit(pre=coeK.prefixer.qb64,
                        sn=10,
                        dig=fake,
                        seal=seal)
        # sign event not receipt
        sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers)  # return Siger if index

        # create receipt message
        vmsg = messagize(reserder, sigers)
        assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"a","t":"vrc","d":"EwxY7Vhkeyr7LBnLAzdGXZzSmTmJV'
                                 b'RctQfNUO0YUqeOU","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy'
                                 b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev'
                                 b'cE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyqst_ZvLo05jau9Gs'
                                 b'F0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA')

        coeKevery.process(ims=vmsg)  # controller process the escrow receipt from validator
        #  check if receipt quadruple in escrow database
        result = coeKevery.db.getVres(key=snKey(pre=coeKever.prefixer.qb64,
                                                   sn=10))
        assert bytes(result[0]) == (fake.encode("utf-8") +
                                    valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        # Send receipt from controller to validator
        # create receipt of validator's inception
        # create seal of controller's last establishment event
        seal = SealEvent(i=coepre,
                         s="{:x}".format(coeKever.lastEst.s),
                         d=coeKever.lastEst.d)
        valK = coeKevery.kevers[valpre]  # lookup valKever from controller's .kevers
        # create validator receipt
        reserder = chit(pre=valK.prefixer.qb64,
                        sn=valK.sn,
                        dig=valK.serder.diger.qb64,
                        seal=seal)
        # sign validator's event not receipt
        # look up event to sign from controller's kever for validator
        valIcpDig = bytes(coeKevery.db.getKeLast(key=snKey(pre=valpre, sn=vsn)))
        assert valIcpDig == valK.serder.diger.qb64b == b'ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcE'
        valIcpRaw = bytes(coeKevery.db.getEvt(key=dgKey(pre=valpre, dig=valIcpDig)))
        assert valIcpRaw == (b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF'
                             b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA'
                             b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl'
                             b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}')

        counter = Counter(CtrDex.ControllerIdxSigs)
        assert counter.qb64 == '-AAB'
        sigers = coeMgr.sign(ser=valIcpRaw, verfers=coeVerfers)  # return Siger if index

        # create receipt message
        cmsg = messagize(reserder, sigers)
        assert cmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF'
                                 b'BDyVSOXYW0","s":"0","t":"vrc","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-'
                                 b'1CEQ89I0E3WevcE","a":{"i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJn'
                                 b'PYabcas","s":"0","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIE'
                                 b'kc"}}-AABAAKXFMBGw559YHoxyeDrmpilQo5JMbr5WSfYTn1IXV_rMtg23_GHrNQ'
                                 b'Ua7y45UkNftT48O0MekxT7geRBU84dACA')

        # controller process own receipt in own Kevery so have copy in own log
        coeKevery.processOne(ims=bytearray(cmsg))  # make copy

        # Simulate sending controller's receipt of validator's inception message to validator
        valKevery.process(ims=cmsg)  # controller process validator's inception and receipt

        #  check if receipt quadruple from controller in validator's receipt database
        result = valKevery.db.getVrcs(key=dgKey(pre=valKever.prefixer.qb64,
                                                   dig=valKever.serder.diger.qb64))
        assert bytes(result[0]) == (coeKever.prefixer.qb64b +
                                    Seqner(sn=coeKever.sn).qb64b +
                                    coeKever.serder.diger.qb64b +
                                    sigers[0].qb64b)
        assert bytes(result[0]) == (b'EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas0AAAAAAAAAAAAAAAAAAAAAAAEy2pXEna'
                                    b'oQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkcAAKXFMBGw559YHoxyeDrmpilQo5JMbr5WSfYTn1I'
                                    b'XV_rMtg23_GHrNQUa7y45UkNftT48O0MekxT7geRBU84dACA')

        # Controller Event 1 Rotation Transferable
        csn += 1
        cesn += 1
        assert csn == cesn == 1
        coeVerfers, coeDigers = coeMgr.rotate(coeVerfers[0].qb64)
        coeSerder = rotate(pre=coeKever.prefixer.qb64,
                           keys=[coeVerfers[0].qb64],
                           dig=coeKever.serder.diger.qb64,
                           nxt=Nexter(digs=[coeDigers[0].qb64]).qb64,
                           sn=csn)
        coe_event_digs.append(coeSerder.dig)

        # sign serialization
        sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers)  # returns sigers

        #  create serialized message
        cmsg = messagize(coeSerder, sigers)

        assert cmsg == bytearray(b'{"v":"KERI10JSON000122_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"1","t":"rot","p":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0'
                                 b'juFL5hOAHAwIEkc","kt":"1","k":["D-HwiqmaETxls3vAVSh0xpXYTs94NUJX'
                                 b'6juupWj_EgsA"],"n":"ED6lKZwg-BWl_jlCrjosQkOEhqKD4BJnlqYqWmhqPhaU'
                                 b'","wt":"0","wr":[],"wa":[],"a":[]}-AABAAsDhyw43CAo29zyTZ7WIuztBG'
                                 b'L3WELM78qSwaEYh8NzwNAPqDtiuL-QmKd22om1qYGDU7cuFM-AlTKaFjsVOzBg')

        # update controller's key event verifier state
        coeKevery.processOne(ims=bytearray(cmsg))  # make copy
        # verify controller's copy of controller's event stream is updated
        assert coeKever.sn == csn
        assert coeKever.serder.diger.qb64 == coeSerder.dig

        # simulate send message from controller to validator
        valKevery.process(ims=cmsg)
        # verify validator's copy of controller's event stream is updated
        assert coeK.sn == csn
        assert coeK.serder.diger.qb64 == coeSerder.dig

        # create receipt of controller's rotation
        # create seal of validator's last establishment event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        # create validator receipt
        reserder = chit(pre=coeK.prefixer.qb64,
                        sn=coeK.sn,
                        dig=coeK.serder.diger.qb64,
                        seal=seal)
        # sign controller's event not receipt
        # look up event to sign from validator's kever for controller
        coeRotDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeRotDig == coeK.serder.diger.qb64b == b'EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek'
        coeRotRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeRotDig)))
        assert coeRotRaw == (b'{"v":"KERI10JSON000122_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",'
                             b'"s":"1","t":"rot","p":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","kt":"1'
                             b'","k":["D-HwiqmaETxls3vAVSh0xpXYTs94NUJX6juupWj_EgsA"],"n":"ED6lKZwg-BWl_jlC'
                             b'rjosQkOEhqKD4BJnlqYqWmhqPhaU","wt":"0","wr":[],"wa":[],"a":[]}')

        sigers = valMgr.sign(ser=coeRotRaw, verfers=valVerfers)

        # validator create receipt message
        vmsg = messagize(reserder, sigers)
        assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"1","t":"vrc","d":"EO7V6wDClWWiN_7sfGDTD8KsfRQaH'
                                 b'yap6fz_O4CYvsek","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy'
                                 b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev'
                                 b'cE"}}-AABAAjVFBjhbM2RdHKEk2rtHA0tXMe0iswn6IS5ShALtR3JHMz-NePCN_f'
                                 b'lUEUbV2F22CGRgmnCe71n42ywWyzsFmDg')

        # validator process own receipt in own kevery so have copy in own log
        valKevery.processOne(ims=bytearray(vmsg))  # make copy

        # Simulate send to controller of validator's receipt of controller's rotation message
        coeKevery.process(ims=vmsg)  # controller process validator's incept and receipt

        # check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ'
                                    b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAAjVFBjhbM2RdHKEk2rtHA0tXMe0iswn6IS5ShAL'
                                    b'tR3JHMz-NePCN_flUEUbV2F22CGRgmnCe71n42ywWyzsFmDg')

        # Next Event 2 Controller Interaction
        csn += 1  # do not increment esn
        assert csn == 2
        assert cesn == 1
        coeSerder = interact(pre=coeKever.prefixer.qb64,
                             dig=coeKever.serder.diger.qb64,
                             sn=csn)
        coe_event_digs.append(coeSerder.dig)

        # sign serialization
        sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers)

        # create msg
        cmsg = messagize(coeSerder, sigers)
        assert cmsg == bytearray(b'{"v":"KERI10JSON000098_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"2","t":"ixn","p":"EO7V6wDClWWiN_7sfGDTD8KsfRQaH'
                                 b'yap6fz_O4CYvsek","a":[]}-AABAAstaU9Hu1ti8erlnFwEdCrXWkkkW_ydYgrr'
                                 b'ryB6EtEOrWY_tQh5jZLGRWrClefeX6AfDDw7JS5JY15n8_ueJWBQ')

        # update controller's key event verifier state
        coeKevery.processOne(ims=bytearray(cmsg))  # make copy
        # verify controller's copy of controller's event stream is updated
        assert coeKever.sn == csn
        assert coeKever.serder.diger.qb64 == coeSerder.dig

        # simulate send message from controller to validator
        valKevery.process(ims=cmsg)
        # verify validator's copy of controller's event stream is updated
        assert coeK.sn == csn
        assert coeK.serder.diger.qb64 == coeSerder.dig

        # create receipt of controller's interaction
        # create seal of validator's last est event
        seal = SealEvent(i=valpre,
                         s="{:x}".format(valKever.lastEst.s),
                         d=valKever.lastEst.d)
        # create validator receipt
        reserder = chit(pre=coeK.prefixer.qb64,
                        sn=coeK.sn,
                        dig=coeK.serder.diger.qb64,
                        seal=seal)
        # sign controller's event not receipt
        # look up event to sign from validator's kever for controller
        coeIxnDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn)))
        assert coeIxnDig == coeK.serder.diger.qb64b == b'EuCLxtdKdRgzzgBnPhTwFKz36u58DqQyMqhX5CUrurPE'
        coeIxnRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIxnDig)))
        assert coeIxnRaw == (b'{"v":"KERI10JSON000098_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",'
                             b'"s":"2","t":"ixn","p":"EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek","a":[]}')

        sigers = valMgr.sign(ser=coeIxnRaw, verfers=valVerfers)

        # create receipt message
        vmsg = messagize(reserder, sigers)
        assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO'
                                 b'CJnPYabcas","s":"2","t":"vrc","d":"EuCLxtdKdRgzzgBnPhTwFKz36u58D'
                                 b'qQyMqhX5CUrurPE","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy'
                                 b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev'
                                 b'cE"}}-AABAAboeSfNNgX04wuUrQp-3eY0oUzcLYnLUmtqYETBZqXEL97pjSjmm81'
                                 b'1KzCRu2cnSHVlKqzIaEBaXyBpWBDexLBQ')

        # ------------------------------END CONVERTED CODE------------------------------

        # validator process own receipt in own kevery so have copy in own log
        valKevery.processOne(ims=bytearray(vmsg))  # make copy

        # Simulate send to controller of validator's receipt of controller's rotation message
        coeKevery.process(ims=vmsg)  # controller process validator's incept and receipt

        #  check if receipt quadruple from validator in receipt database
        result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64,
                                                   dig=coeKever.serder.diger.qb64))
        assert bytes(result[0]) == (valKever.prefixer.qb64b +
                                    Seqner(sn=valKever.sn).qb64b +
                                    valKever.serder.diger.qb64b +
                                    sigers[0].qb64b)

        assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ'
                                    b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAAboeSfNNgX04wuUrQp-3eY0oUzcLYnLUmtqYETB'
                                    b'ZqXEL97pjSjmm811KzCRu2cnSHVlKqzIaEBaXyBpWBDexLBQ')

        #  verify final controller event state
        assert coeKever.sn == coeK.sn == csn

        db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(coepre)]
        assert len(db_digs) == len(coe_event_digs) == csn + 1
        assert db_digs == coe_event_digs == ['Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc',
                                             'EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek',
                                             'EuCLxtdKdRgzzgBnPhTwFKz36u58DqQyMqhX5CUrurPE']

        db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(coepre)]
        assert len(db_digs) == len(coe_event_digs) == csn + 1
        assert db_digs == coe_event_digs

        #  verify final validator event state
        assert valKever.sn == valK.sn == vsn

        db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(valpre)]
        assert len(db_digs) == len(val_event_digs) == vsn + 1
        assert db_digs == val_event_digs == ['ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcE']

        db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(valpre)]
        assert len(db_digs) == len(val_event_digs) == vsn + 1
        assert db_digs == val_event_digs

    assert not os.path.exists(valKevery.db.path)
    assert not os.path.exists(coeKever.baser.path)
Beispiel #8
0
def test_tevery():
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        hab = buildHab(db, kpr)

        vcp = eventing.incept(hab.pre,
                              baks=[],
                              toad=0,
                              cnfg=["NB"],
                              code=MtrDex.Blake3_256)
        regk = vcp.pre

        # successfully anchor to a rotation event
        rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64)

        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)

        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tvy = Tevery(reger=reg, db=db)

        tvy.processEvent(serder=vcp, seqner=seqner, diger=diger)

        assert regk in tvy.tevers
        tev = tvy.tevers[regk]
        assert tev.prefixer.qb64 == vcp.pre
        assert tev.sn == 0

        # send vcp again, get error
        with pytest.raises(LikelyDuplicitousError):
            tvy.processEvent(serder=vcp, seqner=seqner, diger=diger)

        # process issue vc event
        vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU'

        iss = eventing.issue(vcdig=vcdig.decode("utf-8"), regk=regk)

        # successfully anchor to a rotation event
        rseal = SealEvent(iss.ked["i"], iss.ked["s"], iss.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tvy.processEvent(serder=iss, seqner=seqner, diger=diger)
        assert tev.vcState(vcdig) == VcStates.issued
        assert tev.vcSn(vcdig) == 0

        # revoke the vc
        rev = eventing.revoke(vcdig=vcdig.decode("utf-8"),
                              regk=regk,
                              dig=iss.dig)

        # successfully anchor to a rotation event
        rseal = SealEvent(rev.ked["i"], rev.ked["s"], rev.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tvy.processEvent(serder=rev, seqner=seqner, diger=diger)
        assert tev.vcState(vcdig) == VcStates.revoked
        assert tev.vcSn(vcdig) == 1
Beispiel #9
0
def test_tever_backers(mockHelpingNowUTC):
    # registry with backer and receipt
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        valSecret = 'AgjD4nRlycmM5cPcAkfOATAp8wVldRsnc9f1tiwctXlw'

        # create receipt signer prefixer default code is non-transferable
        valSigner = Signer(qb64=valSecret, transferable=False)
        valPrefixer = Prefixer(qb64=valSigner.verfer.qb64)
        valpre = valPrefixer.qb64
        assert valpre == 'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc'

        hab = buildHab(db, kpr)

        vcp = eventing.incept(hab.pre,
                              baks=[valpre],
                              toad=1,
                              cnfg=[],
                              code=MtrDex.Blake3_256)
        regk = vcp.pre
        valCigar = valSigner.sign(ser=vcp.raw, index=0)

        # successfully anchor to a rotation event
        rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64)

        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)

        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev = Tever(serder=vcp,
                    seqner=seqner,
                    diger=diger,
                    bigers=[valCigar],
                    db=db,
                    reger=reg)

        dgkey = dgKey(pre=regk, dig=vcp.dig)
        assert reg.getTvt(dgkey) == (
            b'{"v":"KERI10JSON0000d7_","i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU",'
            b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],'
            b'"bt":"1",'
            b'"b":["B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc"]}')
        assert reg.getAnc(
            dgkey
        ) == b'0AAAAAAAAAAAAAAAAAAAAAAQEpWPsFsCcsu5SpVH0416qHx3gvG0CWlrP_i7BVdbmRBg'
        assert reg.getTel(snKey(
            pre=regk, sn=0)) == b'EJTWiS0ebp8VSyLr38x73dAHdUqivisUtAaGpEHt5HDc'
        assert [bytes(tib) for tib in reg.getTibs(dgkey)] == [
            b'AAGhpPxAoltsRAnqxf7NsBzWSxWYLZ_ALImVVBiTlzJSdlATxRp_hBK4AbOzu-a900hwRxa0RX-yVWbVJA6oxoBw'
        ]
        assert reg.getTwe(snKey(pre=regk, sn=0)) is None

        debSecret = 'AKUotEE0eAheKdDJh9QvNmSEmO_bjIav8V_GmctGpuCQ'

        # create receipt signer prefixer default code is non-transferable
        debSigner = Signer(qb64=debSecret, transferable=False)
        debPrefixer = Prefixer(qb64=debSigner.verfer.qb64)
        debpre = debPrefixer.qb64
        assert debpre == 'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI'

        vrt = eventing.rotate(regk, dig=vcp.dig, baks=[valpre], adds=[debpre])
        valCigar = valSigner.sign(ser=vrt.raw, index=0)
        debCigar = debSigner.sign(ser=vrt.raw, index=1)

        # successfully anchor to a rotation event
        rseal = SealEvent(regk, vrt.ked["s"], vrt.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev.update(serder=vrt,
                   seqner=seqner,
                   diger=diger,
                   bigers=[valCigar, debCigar])

        assert tev.baks == [
            'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc',
            'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI'
        ]

        vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU'

        bis = eventing.backerIssue(vcdig=vcdig.decode("utf-8"),
                                   regk=regk,
                                   regsn=tev.sn,
                                   regd=tev.serder.dig)
        valCigar = valSigner.sign(ser=bis.raw, index=0)
        debCigar = debSigner.sign(ser=bis.raw, index=1)

        # successfully anchor to a rotation event
        rseal = SealEvent(bis.ked["i"], bis.ked["s"], bis.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev.update(bis,
                   seqner=seqner,
                   diger=diger,
                   bigers=[valCigar, debCigar])

        vci = nsKey([regk, vcdig])
        dgkey = dgKey(pre=vci, dig=bis.dig)
        assert bytes(reg.getTvt(dgkey)) == (
            b'{"v":"KERI10JSON00012d_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",'
            b'"ii":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":"0","t":"bis","ra":{'
            b'"i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":1,"d":"EZH2Cfw3nvcMRg'
            b'Y31Jyc2zHVh4a0LO_bVZ4EmL4V8Ol8"},"dt":"2021-01-01T00:00:00.000000+00:00"}'
        )
Beispiel #10
0
def test_tever_no_backers(mockHelpingNowUTC):
    # registry with no backers
    # registry with backer and receipt
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        hab = buildHab(db, kpr)

        vcp = eventing.incept(hab.pre,
                              baks=[],
                              toad=0,
                              cnfg=["NB"],
                              code=MtrDex.Blake3_256)
        regk = vcp.pre

        # successfully anchor to a rotation event
        rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64)

        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)

        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev = Tever(serder=vcp, seqner=seqner, diger=diger, db=db, reger=reg)

        assert tev.prefixer.qb64 == vcp.pre
        assert tev.sn == 0

        dgkey = dgKey(pre=regk, dig=vcp.dig)
        assert reg.getTvt(dgkey) == (
            b'{"v":"KERI10JSON0000ad_","i":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw",'
            b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":["NB"],"bt":"0","b":[]}'
        )

        assert reg.getAnc(dgkey) == (
            b'0AAAAAAAAAAAAAAAAAAAAAAQE-yQ6BjCaJg-u2mNuE-ycVWVTq7IZ8TuN-Ew8soLijSA'
        )
        assert reg.getTel(snKey(
            pre=regk, sn=0)) == b'ElYstqTocyQixLLz4zYCAs2unaFco_p6LqH0W01loIg4'
        assert reg.getTibs(dgkey) == []
        assert reg.getTwe(snKey(pre=regk, sn=0)) is None

        # try to rotate a backerless registry
        vrt = eventing.rotate(regk, dig=vcp.dig)
        rseal = SealEvent(regk, vrt.ked["s"], vrt.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        # should raise validation err because rotation is not supported
        with pytest.raises(ValidationError):
            tev.update(serder=vrt, seqner=seqner, diger=diger)

        vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU'

        iss = eventing.issue(vcdig=vcdig.decode("utf-8"), regk=regk)

        # successfully anchor to a rotation event
        rseal = SealEvent(iss.ked["i"], iss.ked["s"], iss.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev.update(iss, seqner=seqner, diger=diger)

        vci = nsKey([regk, vcdig])
        dgkey = dgKey(pre=vci, dig=iss.dig)
        assert bytes(reg.getTvt(dgkey)) == (
            b'{"v":"KERI10JSON0000ba_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",'
            b'"s":"0","t":"iss","ri":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw","dt":"'
            b'2021-01-01T00:00:00.000000+00:00"}')
        assert bytes(
            reg.getAnc(dgkey)
        ) == b'0AAAAAAAAAAAAAAAAAAAAAAwEJLLpuUKPSDIcoOAOArQBzceWc8MoShm-cDL-w81liIw'

        # revoke vc with no backers
        rev = eventing.revoke(vcdig=vcdig.decode("utf-8"),
                              regk=regk,
                              dig=iss.dig)

        # successfully anchor to a rotation event
        rseal = SealEvent(rev.ked["i"], rev.ked["s"], rev.diger.qb64)
        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)
        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        tev.update(rev, seqner=seqner, diger=diger)
        dgkey = dgKey(pre=vci, dig=rev.dig)
        assert bytes(reg.getTvt(dgkey)) == (
            b'{"v":"KERI10JSON0000ed_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",'
            b'"s":"1","t":"rev","ri":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw","p":"E'
            b'C9PffPrvyaKzsn72SWTvgyvWCJ1FbDThvJhsQ9LWo9M","dt":"2021-01-01T00:00:00.00000'
            b'0+00:00"}')
Beispiel #11
0
def test_tever_escrow():
    with pytest.raises(TypeError):
        Tever()

    # registry with no backers, invalid anchor
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        hab = buildHab(db, kpr)
        vcp = eventing.incept(hab.pre,
                              baks=[],
                              toad=0,
                              cnfg=[],
                              code=MtrDex.Blake3_256)
        regk = vcp.pre
        assert regk == "EoN_Ln_JpgqsIys-jDOH8oWdxgWqs7hzkDGeLWHb9vSY"
        assert vcp.dig == "EvpB-_BWD7tOhLI0cDyEQbziBt6IMyQnkrh0booR4vhg"
        assert vcp.ked["ii"] == hab.pre

        # anchor to nothing, exception expected
        seqner = Seqner(sn=4)

        # invalid seal sn
        with pytest.raises(ValidationError):
            Tever(serder=vcp, seqner=seqner, diger=None, db=db, reger=reg)

    # registry with no backers
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        hab = buildHab(db, kpr)
        vcp = eventing.incept(hab.pre,
                              baks=[],
                              toad=0,
                              cnfg=[],
                              code=MtrDex.Blake3_256)
        regk = vcp.pre

        # anchoring event not in db, exception and escrow
        seqner = Seqner(sn=1)

        with pytest.raises(MissingAnchorError):
            Tever(serder=vcp, seqner=seqner, db=db, reger=reg)

        dgkey = dgKey(pre=regk, dig=vcp.dig)
        assert reg.getTvt(dgkey) == (
            b'{"v":"KERI10JSON0000a9_","i":"EoN_Ln_JpgqsIys-jDOH8oWdxgWqs7hzkDGeLWHb9vSY",'
            b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],"bt":"0","b":[]}'
        )
        assert reg.getTae(snKey(
            pre=regk, sn=0)) == b'EvpB-_BWD7tOhLI0cDyEQbziBt6IMyQnkrh0booR4vhg'

    # registry with backers, no signatures.  should escrow
    with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg(
    ) as reg:
        hab = buildHab(db, kpr)
        vcp = eventing.incept(
            hab.pre,
            baks=["BoOcciw30IVQsaenKXpiyMVrjtPDW3KeD_6KFnSfoaqI"],
            toad=1,
            cnfg=[],
            code=MtrDex.Blake3_256)
        regk = vcp.pre

        # successfully anchor to a rotation event
        rseal = SealEvent(regk, vcp.ked["s"], vcp.diger.qb64)

        rot = hab.rotate(data=[rseal._asdict()])
        rotser = Serder(raw=rot)

        seqner = Seqner(sn=int(rotser.ked["s"], 16))
        diger = rotser.diger

        with pytest.raises(MissingWitnessSignatureError):
            Tever(serder=vcp, seqner=seqner, diger=diger, db=db, reger=reg)

        dgkey = dgKey(pre=regk, dig=vcp.dig)
        assert reg.getTvt(dgkey) == (
            b'{"v":"KERI10JSON0000d7_","i":"E1cv04kvHvWPrfncYsq-lQ-QvyKmKz6-hlGj02B2QWbk",'
            b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],"bt":"1",'
            b'"b":["BoOcciw30IVQsaenKXpiyMVrjtPDW3KeD_6KFnSfoaqI"]}')

        assert reg.getAnc(dgkey) == (
            b'0AAAAAAAAAAAAAAAAAAAAAAQE1NdOqtN0HlhBPc7-MHvsA4vajMwFYp2eIturQQo0stM'
        )
        assert reg.getTel(snKey(pre=regk, sn=0)) is None
        assert reg.getTwe(snKey(
            pre=regk, sn=0)) == b'EjhsbizNCwN_EFuOxbUt8CN0xOctGRIVOW8X-XqA3fSk'