示例#1
0
def test_build_proof():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64

    with basing.openDB(name="sid") as sigDB, \
            keeping.openKS(name="sid") as sigKS:
        sigHab = habbing.Habitat(ks=sigKS, db=sigDB, salt=sidSalt, icount=3, ncount=3, temp=True)

        sed = dict()
        sed["$id"] = ""
        sed["$schema"] = "http://json-schema.org/draft-07/schema#"
        sed.update(dict(
            type="object",
            properties=dict(
                id=dict(
                    type="string"
                ),
                lei=dict(
                    type="string"
                )
            )
        ))

        schemer = scheming.Schemer(sed=sed, typ=scheming.JSONSchema(), code=coring.MtrDex.Blake3_256)
        credSubject = dict(
            id="did:keri:Efaavv0oadfghasdfn443fhbyyr4v",  # this needs to be generated from a KEL
            lei="254900OPPU84GM83MG36",
            issuanceDate="2021-06-27T21:26:21.233257+00:00",
        )

        cache = CacheResolver()
        cache.add(schemer.said, schemer.raw)

        creder = credential(issuer=sigHab.pre,
                            schema=schemer.said,
                            subject=credSubject,
                            typ=JSONSchema(resolver=cache))

        sigHab.rotate()
        sigHab.rotate()
        sigHab.rotate()
        sigHab.rotate()

        prefixer = coring.Prefixer(qb64=sigHab.kever.prefixer.qb64)
        seqner = coring.Seqner(sn=sigHab.kever.lastEst.s)
        diger = coring.Diger(qb64=sigHab.kever.lastEst.d)

        sigers = sigHab.mgr.sign(ser=creder.raw, verfers=sigHab.kever.verfers, indexed=True)

        proof = buildProof(prefixer, seqner, diger, sigers)
        assert proof == (
            b'-FABEiRjCnZfca8gUZqecerjGpjkiY8dIkGudP6GfapWi5MU0AAAAAAAAAAAAAAAAAAAAABAECc96yX1sYswnD6LXEcoNuJ0e'
            b'hi8gkFMEGedqURhXMBU-AADAAGcSUhma16SY3MiKU7n6mK3JzWS2oAiBRB-jeycIDrQ2Z-36QHrMorzRAO9Iw7FvIKrneaLZP'
            b'whz6DFFiXM4oBgAB1g2CudOfOFd9BqesyAIlCDRAkxAQynrED4_ot1MkhKwjmK71XUx1Xer25iWtHMa9sny07AsTO-KE3vu9e'
            b'qTPDQAClDQMXWg3I8qeVEjA6JA9xBW2uESMtMzNVQ8lH31UCizqYVjXort--QEJTsfIt_b0Qq1JOCtaj7Y6U-DWHoulBA')

        prefixer, seqner, diger, isigers = parseProof(proof)
        assert prefixer.qb64 == sigHab.pre
        assert diger.qb64 == sigHab.kever.lastEst.d
        assert seqner.sn == 4
        assert len(isigers) == 3
示例#2
0
def test_weighted():
    """
    Test multisig with weighted threshold

    """
    wesSalt = coring.Salter(raw=b'0123456789abcdef').qb64  # init wes Salter

    # init event DB and keep DB
    with dbing.openDB(name="wes") as wesDB, keeping.openKS(
            name="wes") as wesKS:
        # Init key pair manager
        wesMgr = keeping.Manager(keeper=wesKS, salt=wesSalt)

        # Init Kevery with event DB
        wesKvy = eventing.Kevery(db=wesDB)

        # create inception event for Wes with 3 keys each in incept and next sets
        # defaults are algo salty and rooted
        sith = ["1/2", "1/2", "1/2"]  #  2 of 3 but with weighted threshold
        nxtsith = ["1/2", "1/2", "1/2"]
        verfers, digers, cst, nst = wesMgr.incept(icount=3,
                                                  isith=sith,
                                                  ncount=3,
                                                  nsith=nxtsith,
                                                  stem='wes',
                                                  temp=True)
        assert cst == nst == sith

        wesSrdr = eventing.incept(
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            code=coring.MtrDex.Blake3_256)

        wesPre = wesSrdr.ked["i"]

        wesMgr.move(old=verfers[0].qb64,
                    new=wesPre)  # move key pair label to prefix

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000154_","i":"EM8ac0UPJZCaWOw2uRcvx6FaygyxFvGzA5'
            b'MTob9WfbDQ","s":"0","t":"icp","kt":["1/2","1/2","1/2"],"k":["DK4'
            b'OJI8JOr6oEEUMeSF_X-SbKysfwpKwW-ho5KARvH5c","D1RZLgYke0GmfZm-CH8A'
            b'sW4HoTU4m-2mFgu8kbwp8jQU","DBVwzum-jPfuUXUcHEWdplB4YcoL3BWGXK0TM'
            b'oF_NeFU"],"n":"EhJGhyJQTpSlZ9oWfQT-lHNl1woMazLC42O89fRHocTI","wt'
            b'":"0","w":[],"c":[]}-AADAAc4jIKyjjpK7rJzywkX2AXXaNGgUGfcUgT6fm7P'
            b'iqL8H8tDsxHb6dcnybE7Hc34jtUq47OWWwCV3K9oCTUUAHAwABlP9qpCcMow8Lq5'
            b'bzE-DLHlItNuQYD9SqOQDNyJoTpk_BEW6Q8UIG012MJEM7GoFTMV5H9UUztQfSQp'
            b'l9Jh9lBQACVn_l3CTPIrCyGZpvW9qxVfZll0su-vIv1gvx0GQfo1qAMNk4c_7t-x'
            b'bXKTw3hwDPt46m5zGd38Y3qIEwQD3jCA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        wesK = wesKvy.kevers[wesPre]  # kever created so event was validated
        assert wesK.prefixer.qb64 == wesPre
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # create interaction event for Wes
        wesSrdr = eventing.interact(pre=wesK.prefixer.qb64,
                                    dig=wesK.serder.diger.qb64,
                                    sn=wesK.sn + 1,
                                    data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=wesK.verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000098_","i":"EM8ac0UPJZCaWOw2uRcvx6FaygyxFvGzA5'
            b'MTob9WfbDQ","s":"1","t":"ixn","p":"E3-lhMd85oc8Uwrd_7c6xUy5tvZhr'
            b'b9ZHvcOO4HxHB1c","a":[]}-AADAAWmzu83wDFTn9Hc6_xskGe8Ed_PhiOpVQ2H'
            b'kxAx28qgLP_Zz7pwCsvmRDM1x9sL8Ygg7hQman5qDaeJS4fJm1DQABlc4hfziecy'
            b'_DXVN2a8AttmuBL_Oh0-Ro_Rz3Mf6KWOJTMLQIHaRJ62L01Q5vP6KmiSr2zwJUT_'
            b'urfGLZoaRUBwACt4l7pTFqmzfzk6p6FKlT1KGXYJ2ea2SmU7I-7agz0i4lCDNQf-'
            b'Y_NJWs6NTWEs5vsPOskNcGnr8nIpQ51N1qBQ')

        # apply msg to wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        nxtsith = ["1/2", "1/2", "1/2"]  #  2 of 3 but with weighted threshold
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=3,
                                                  sith=nxtsith,
                                                  temp=True)
        assert nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000190_","i":"EM8ac0UPJZCaWOw2uRcvx6FaygyxFvGzA5'
            b'MTob9WfbDQ","s":"2","t":"rot","p":"E6wjlP_oqJzmo65d56XuTL602ABcK'
            b'X0ZBEy9M-k7E1Eg","kt":["1/2","1/2","1/2"],"k":["DeonYM2bKnAwp6VZ'
            b'cuCXdX72kNFw56czlZ_Tc7XHHVGI","DQghKIy-2do9OkweSgazh3Ql1vCOt5bnc'
            b'5QF8x50tRoU","DNAUn-5dxm6b8Njo01O0jlStMRCjo9FYQA2mfqFW1_JA"],"n"'
            b':"EX5fxvjOg5VuDboWbqnTjTPpXa3nNIm99hlsB1EmhTo8","wt":"0","wr":[]'
            b',"wa":[],"a":[]}-AADAApZ3U4zacSPm5embDTRD2IxB1e4FrdAToP-tsXB-VVp'
            b'fX6Yk78iIdFyeNi9U_sgefzvhR3_mH5Bj_ZlfpEMCQDAABWURvCkE1HjbE_noEqj'
            b'BWEpdG1hUfP3_Oye5Ys0zquigDrOSv2ApXzlq1-ALDTZeqMX4lbVlqubRjDu3Qog'
            b'xrAgACtyNpfXHvly2emXyAdJ5sAVUVCnodONK2CG8WGipISYLGIlyfmNoTVeHw-f'
            b'_3ZY2tAgbmLZika4kEL8REfr5VCA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        sith = nxtsith  # rotate so nxtsith is now current sith and need new nextsith
        #  2 of first 3 and 1 of last 2
        nxtsith = [["1/2", "1/2", "1/2"], ["1/1", "1/1"]]
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=5,
                                                  sith=nxtsith,
                                                  temp=True)
        assert cst == sith
        assert nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000190_","i":"EM8ac0UPJZCaWOw2uRcvx6FaygyxFvGzA5'
            b'MTob9WfbDQ","s":"3","t":"rot","p":"E9tuWqXCN31LqElTSdfGp3lWDetle'
            b'T4Pa9tuSUi2V87k","kt":["1/2","1/2","1/2"],"k":["D7WWKDLVwYxYMLAj'
            b'DceIEs66xPMY4Afzx-RQw2x0mQzI","Dmg6Aah8qyKKDiQyNXTiO71QJwizjZfGM'
            b'61BA-s0A5F4","DS3fhKpvPCDL5WmfN4_PkmJMMsSCdRTxG24OQuf_EmHQ"],"n"'
            b':"EcM4iw7fElXWhad8V-za4Px7nBKjndxoh3XZRkohghKY","wt":"0","wr":[]'
            b',"wa":[],"a":[]}-AADAAO0Ma_uiLbrXrqkNsLccCNgWcfvopoo2NwZ5aJLKBa9'
            b'7OMuZibsiVL6bDues9r65o2Tq1hzuuQQK6cHg_OH3xDAAB-cLMTqhogxrxyhMVoP'
            b'RXJ-rtQaV5oEsXSqcU3phI0bxFJvtydfnySe30LXbOwnFS-_HhCRMOulhBdcAvFR'
            b'dKAAACXhumJPsAS1UWSjlKiSby_TCC_W82jkTcvWBB4pwrcYmno8jRpQoB0ubPyG'
            b'96I2RqNql0Q9p5LcMPsLtT_Zt4DA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        sith = nxtsith  # rotate so nxtsith is now current sith and need new nextsith
        #  2 of first 3 and 1 of last 2
        nxtsith = [["1/2", "1/2", "1/2"], ["1/1", "1/1"]]
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=5,
                                                  sith=nxtsith,
                                                  temp=True)
        assert cst == nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON0001fe_","i":"EM8ac0UPJZCaWOw2uRcvx6FaygyxFvGzA5'
            b'MTob9WfbDQ","s":"4","t":"rot","p":"EkBxzyMDQGRCNmoMOWwh58wuNuERR'
            b'cLoMH2_F0w99Dw4","kt":[["1/2","1/2","1/2"],["1/1","1/1"]],"k":["'
            b'DToUWoemnetqJoLFIqDI7lxIJEfF0W7xG5ZlqAseVUQc","Drz-IZjko61q-sPMD'
            b'IW6n-0NGFubbXiZhzWZrO_BZ0Wc","DiGwL3hjQqiUgQlFPeA6kRR1EBXX0vSLm9'
            b'b6QhPS8IkQ","Dxj5pcStgZ6CbQ2YktNaj8KLE_g9YAOZF6AL9fyLcWQw","DE5z'
            b'r5eH8EUVQXyAaxWfQUWkGCId-QDCvvxMT77ibj2Q"],"n":"E3in3Z14va0kk4Wq'
            b'd3vcCAojKNtQq7ZTrQaavR8x0yu4","wt":"0","wr":[],"wa":[],"a":[]}-A'
            b'AFAAEjpPTMtLre--y96OaTckIov-qfWT1lqOvwNBAcdTfmsfCLIJgZO4Y2ybJqGw'
            b'l2Q6DqLdfNQWHiDwnyllo1zZBgABny8aZlKENxCnulxSzSWIbFsg1Kv7RrdgTt4r'
            b'19taFq-bmBmMTLrkidNbeMHwgsNhhT8f3KJnPTaHEZ2Myd3BDQACaJ2sc2SpEcM0'
            b'9qMbk-8maWuxjAdMCb8n5P1vJesnf7TW6p3Vu2Mart5HuXW44r79DQ91sAmyYB_0'
            b'4q--ZyNYAQAD5trFl0S9G0GQmFF7FCgMYWzKNe7x16622OvT1-HjDP-eXxf9dani'
            b'dlUIbVWqalLgXOdhhsCNUDasvOHLByjSBgAEs-ovUeu2--2wnCJLpfHzLZUbc5fL'
            b'8bpOShEoPUwxEH4H1Wxsn3xPlvL3_pe5Mun3sq2jIhl1EOjcDaKOHofZCA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

    assert not os.path.exists(wesKS.path)
    assert not os.path.exists(wesDB.path)
    """End Test"""
示例#3
0
def test_crypt_signer_suber():
    """
    test Manager class with aeid
    """
    # preseed = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES)
    seed0 = (
        b'\x18;0\xc4\x0f*vF\xfa\xe3\xa2Eee\x1f\x96o\xce)G\x85\xe3X\x86\xda\x04\xf0\xdc'
        b'\xde\x06\xc0+')
    signer0 = coring.Signer(raw=seed0, code=coring.MtrDex.Ed25519_Seed)
    assert signer0.verfer.code == coring.MtrDex.Ed25519
    assert signer0.verfer.transferable  # default
    assert signer0.qb64b == b'AGDswxA8qdkb646JFZWUflm_OKUeF41iG2gTw3N4GwCs'
    assert signer0.verfer.qb64b == b'DhixhZjC1Wj2bLR1QdADT79kS2zwHld29ekca0elxHiE'

    # preseed = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES)
    seed1 = (
        b'`\x05\x93\xb9\x9b6\x1e\xe0\xd7\x98^\x94\xc8Et\xf2\xc4\xcd\x94\x18'
        b'\xc6\xae\xb9\xb6m\x12\xc4\x80\x03\x07\xfc\xf7')

    signer1 = coring.Signer(raw=seed1, code=coring.MtrDex.Ed25519_Seed)
    assert signer1.verfer.code == coring.MtrDex.Ed25519
    assert signer1.verfer.transferable  # default
    assert signer1.qb64b == b'AYAWTuZs2HuDXmF6UyEV08sTNlBjGrrm2bRLEgAMH_Pc'
    assert signer1.verfer.qb64b == b'Dgekf6SB_agwx96mVSZI6PTC09j4Sp8qUbgKglN8uLjY'

    # rawsalt =pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES)
    rawsalt = b'0123456789abcdef'
    salter = coring.Salter(raw=rawsalt)
    salt = salter.qb64
    assert salt == '0AMDEyMzQ1Njc4OWFiY2RlZg'
    stem = "blue"

    # cryptseed0 = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES)
    cryptseed0 = b'h,#|\x8ap"\x12\xc43t2\xa6\xe1\x18\x19\xf0f2,y\xc4\xc21@\xf5@\x15.\xa2\x1a\xcf'
    cryptsigner0 = coring.Signer(raw=cryptseed0,
                                 code=coring.MtrDex.Ed25519_Seed,
                                 transferable=False)
    seed0 = cryptsigner0.qb64
    aeid0 = cryptsigner0.verfer.qb64
    assert aeid0 == 'BJruYr3oXDGRTRN0XnhiqDeoENdRak6FD8y2vsTvvJkE'

    decrypter = coring.Decrypter(seed=seed0)
    encrypter = coring.Encrypter(verkey=aeid0)
    assert encrypter.verifySeed(seed=seed0)

    # cryptseed1 = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES)
    cryptseed1 = (
        b"\x89\xfe{\xd9'\xa7\xb3\x89#\x19\xbec\xee\xed\xc0\xf9\x97\xd0\x8f9\x1dyNI"
        b'I\x98\xbd\xa4\xf6\xfe\xbb\x03')
    cryptsigner1 = coring.Signer(raw=cryptseed1,
                                 code=coring.MtrDex.Ed25519_Seed,
                                 transferable=False)

    with dbing.openLMDB() as db, keeping.openKS() as ks:
        assert isinstance(db, dbing.LMDBer)
        assert db.name == "test"
        assert db.opened

        sdb = subing.CryptSignerSuber(db=db,
                                      subkey='bags.')  # default klas is Signer
        assert isinstance(sdb, subing.CryptSignerSuber)
        assert issubclass(sdb.klas, coring.Signer)

        # Test without encrypter or decrypter
        keys = (signer0.verfer.qb64,
                )  # must be verfer as key to get transferable
        sdb.put(keys=keys, val=signer0)
        actual = sdb.get(keys=keys)
        assert isinstance(actual, coring.Signer)
        assert actual.qb64 == signer0.qb64
        assert actual.verfer.qb64 == signer0.verfer.qb64

        sdb.rem(keys)
        actual = sdb.get(keys=keys)
        assert actual is None

        sdb.put(keys=keys, val=signer0)
        actual = sdb.get(keys=keys)
        assert isinstance(actual, coring.Signer)
        assert actual.qb64 == signer0.qb64
        assert actual.verfer.qb64 == signer0.verfer.qb64

        #  try put different val when already put
        result = sdb.put(keys=keys, val=signer1)
        assert not result
        assert isinstance(actual, coring.Signer)
        assert actual.qb64 == signer0.qb64
        assert actual.verfer.qb64 == signer0.verfer.qb64

        #  now overwrite with pin. Key is wrong but transferable property is
        #  the same so that is all that matters to get back signer
        result = sdb.pin(keys=keys, val=signer1)
        assert result
        actual = sdb.get(keys=keys)
        assert isinstance(actual, coring.Signer)
        assert actual.qb64 == signer1.qb64
        assert actual.verfer.qb64 == signer1.verfer.qb64

        # test with keys as string not tuple
        keys = signer0.verfer.qb64

        sdb.pin(keys=keys, val=signer0)
        actual = sdb.get(keys=keys)
        assert isinstance(actual, coring.Signer)
        assert actual.qb64 == signer0.qb64
        assert actual.verfer.qb64 == signer0.verfer.qb64

        sdb.rem(keys)
        assert not sdb.get(keys=keys)

        # test missing entry at keys
        badkey = b'D1QdADT79kS2zwHld29hixhZjC1Wj2bLRekca0elxHiE'
        assert not sdb.get(badkey)

        # test iteritems
        sdb = subing.CryptSignerSuber(db=db, subkey='pugs.')
        assert isinstance(sdb, subing.CryptSignerSuber)
        assert sdb.put(keys=signer0.verfer.qb64b, val=signer0)
        assert sdb.put(keys=signer1.verfer.qb64b, val=signer1)

        items = [(keys, sgnr.qb64) for keys, sgnr in sdb.getItemIter()]
        assert items == [((signer1.verfer.qb64, ), signer1.qb64),
                         ((signer0.verfer.qb64, ), signer0.qb64)]

        # now test with encrypter and decrypter
        encrypter0 = coring.Encrypter(verkey=cryptsigner0.verfer.qb64)
        decrypter0 = coring.Decrypter(seed=cryptsigner0.qb64b)

        # first pin with encrypter
        assert sdb.pin(keys=signer0.verfer.qb64b,
                       val=signer0,
                       encrypter=encrypter0)
        assert sdb.pin(keys=signer1.verfer.qb64b,
                       val=signer1,
                       encrypter=encrypter0)

        # now get
        actual0 = sdb.get(keys=signer0.verfer.qb64b, decrypter=decrypter0)
        assert isinstance(actual0, coring.Signer)
        assert actual0.qb64 == signer0.qb64
        assert actual0.verfer.qb64 == signer0.verfer.qb64

        actual1 = sdb.get(keys=signer1.verfer.qb64b, decrypter=decrypter0)
        assert isinstance(actual1, coring.Signer)
        assert actual1.qb64 == signer1.qb64
        assert actual1.verfer.qb64 == signer1.verfer.qb64

        # now get without decrypter
        with pytest.raises(ValueError):
            actual0 = sdb.get(keys=signer0.verfer.qb64b)

        with pytest.raises(ValueError):
            actual1 = sdb.get(keys=signer1.verfer.qb64b)

        # remove and test put
        sdb.rem(keys=signer0.verfer.qb64b)
        assert not sdb.get(keys=signer0.verfer.qb64b)
        sdb.rem(keys=signer1.verfer.qb64b)
        assert not sdb.get(keys=signer1.verfer.qb64b)

        assert sdb.put(keys=signer0.verfer.qb64b,
                       val=signer0,
                       encrypter=encrypter0)
        assert sdb.put(keys=signer1.verfer.qb64b,
                       val=signer1,
                       encrypter=encrypter0)

        items = [(keys, sgnr.qb64)
                 for keys, sgnr in sdb.getItemIter(decrypter=decrypter0)]
        assert items == [((signer1.verfer.qb64, ), signer1.qb64),
                         ((signer0.verfer.qb64, ), signer0.qb64)]

        # test re-encrypt
        encrypter1 = coring.Encrypter(verkey=cryptsigner1.verfer.qb64)
        decrypter1 = coring.Decrypter(seed=cryptsigner1.qb64b)
        for keys, sgnr in sdb.getItemIter(decrypter=decrypter0):
            sdb.pin(keys, sgnr, encrypter=encrypter1)

        items = [(keys, sgnr.qb64)
                 for keys, sgnr in sdb.getItemIter(decrypter=decrypter1)]
        assert items == [((signer1.verfer.qb64, ), signer1.qb64),
                         ((signer0.verfer.qb64, ), signer0.qb64)]

        # now test with manager
        manager = keeping.Manager(
            ks=ks,
            seed=seed0,
            salt=salt,
            aeid=aeid0,
        )
        assert manager.ks.opened
        assert manager.inited
        assert manager._inits == {
            'aeid': 'BJruYr3oXDGRTRN0XnhiqDeoENdRak6FD8y2vsTvvJkE',
            'salt': '0AMDEyMzQ1Njc4OWFiY2RlZg'
        }
        assert manager.encrypter.qb64 == encrypter.qb64  #  aeid provided
        assert manager.decrypter.qb64 == decrypter.qb64  # aeid and seed provided
        assert manager.seed == seed0  # in memory only
        assert manager.aeid == aeid0  # on disk only
        assert manager.salt == salt  # encrypted on disk but property decrypts if seed
        assert manager.pidx == 0
        assert manager.tier == coring.Tiers.low
        saltCipher0 = coring.Cipher(qb64=manager.ks.gbls.get('salt'))
        assert saltCipher0.decrypt(seed=seed0).qb64 == salt

        manager.updateAeid(aeid=cryptsigner1.verfer.qb64,
                           seed=cryptsigner1.qb64)
        assert manager.aeid == cryptsigner1.verfer.qb64 == 'BRw6sysb_uv81ZouXqHxQlqnAh9BYiSOsg9eQJmbZ8Uw'
        assert manager.salt == salt
        saltCipher1 = coring.Cipher(qb64=manager.ks.gbls.get('salt'))
        assert not saltCipher0.qb64 == saltCipher1.qb64  # old cipher different
    """End Test"""
示例#4
0
def test_delegation():
    """
    Test creation and validation of delegated identifer prefixes and events

    """
    # bob is the delegator del is bob's delegate

    bobSalt = coring.Salter(raw=b'0123456789abcdef').qb64
    delSalt = coring.Salter(raw=b'abcdef0123456789').qb64

    with basing.openDB(name="bob") as bobDB, \
          keeping.openKS(name="bob") as bobKS, \
          basing.openDB(name="del") as delDB, \
          keeping.openKS(name="del") as delKS:

        # Init key pair managers
        bobMgr = keeping.Manager(keeper=bobKS, salt=bobSalt)
        delMgr = keeping.Manager(keeper=delKS, salt=delSalt)

        # Init Keverys
        bobKvy = eventing.Kevery(db=bobDB)
        delKvy = eventing.Kevery(db=delDB)

        # Setup Bob by creating inception event
        verfers, digers, cst, nst = bobMgr.incept(
            stem='bob', temp=True)  # algo default salty and rooted
        bobSrdr = eventing.incept(
            keys=[verfer.qb64 for verfer in verfers],
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64,
            code=coring.MtrDex.Blake3_256)

        bob = bobSrdr.ked["i"]
        assert bob == 'Eta8KLf1zrE5n-HZpgRAnDmxLASZdXEiU9u6aahqR8TI'

        bobMgr.move(old=verfers[0].qb64,
                    new=bob)  # move key pair label to prefix

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=verfers)

        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == (
            b'{"v":"KERI10JSON0000ed_","i":"Eta8KLf1zrE5n-HZpgRAnDmxLASZdXEiU9'
            b'u6aahqR8TI","s":"0","t":"icp","kt":"1","k":["DqI2cOZ06RwGNwCovYU'
            b'WExmdKU983IasmUKMmZflvWdQ"],"n":"E7FuL3Z_KBgt_QAwuZi1lUFNC69wvyH'
            b'SxnMFUsKjZHss","bt":"0","b":[],"c":[],"a":[]}-AABAAp8S6RgfLwdCEi'
            b'z0jL9cXaDwTJF6MLuKyXp7EfJtrp2myOikOJVUB-w9UGZc1Y8dnURxhXPSca-ZEU'
            b'AV73XOaAw')

        # apply msg to bob's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=bobKvy)
        # bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        bobK = bobKvy.kevers[bob]
        assert bobK.prefixer.qb64 == bob
        assert bobK.serder.diger.qb64 == bobSrdr.dig
        assert bobK.serder.diger.qb64 == 'E1-QL0TCdsBTRaKoakLjFhjSlELK60Vv8WdRaG6zMnTM'

        # apply msg to del's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=delKvy)
        # delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert bob in delKvy.kevers

        # Setup Del's inception event assuming that Bob's next event will be an ixn delegating event
        verfers, digers, cst, nst = delMgr.incept(
            stem='del', temp=True)  # algo default salty and rooted

        delSrdr = eventing.delcept(
            keys=[verfer.qb64 for verfer in verfers],
            delpre=bobK.prefixer.qb64,
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64)

        delPre = delSrdr.ked["i"]
        assert delPre == 'E-9tsnVcfUyXVQyBPGfntoL-xexf4Cldt_EPzHis2W4U'

        delMgr.move(old=verfers[0].qb64,
                    new=delPre)  # move key pair label to prefix
        assert delSrdr.dig == 'E1x1JOub6oEQkxAxTNFu1Pma6y-lrbprNsaILHJHoPmY'

        # Now create delegating event
        seal = eventing.SealEvent(i=delPre, s=delSrdr.ked["s"], d=delSrdr.dig)
        bobSrdr = eventing.interact(pre=bobK.prefixer.qb64,
                                    dig=bobK.serder.diger.qb64,
                                    sn=bobK.sn + 1,
                                    data=[seal._asdict()])

        assert bobSrdr.dig == 'E3fUycq1G-P1K1pL2OhvY6ZU-9otSa3hXiCcrxuhjyII'

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=bobK.verfers)
        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == (
            b'{"v":"KERI10JSON000107_","i":"Eta8KLf1zrE5n-HZpgRAnDmxLASZdXEiU9'
            b'u6aahqR8TI","s":"1","t":"ixn","p":"E1-QL0TCdsBTRaKoakLjFhjSlELK6'
            b'0Vv8WdRaG6zMnTM","a":[{"i":"E-9tsnVcfUyXVQyBPGfntoL-xexf4Cldt_EP'
            b'zHis2W4U","s":"0","d":"E1x1JOub6oEQkxAxTNFu1Pma6y-lrbprNsaILHJHo'
            b'PmY"}]}-AABAAROVSK0qK2gqlr_OUsnHNW_ksCyLVmRaysRne2dI5dweECGIy3_Z'
            b'uFHyOofiDRt5tRE09PlS0uZdot6byFNr-AA')

        # apply msg to bob's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=bobKvy)
        # bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert bobK.serder.diger.qb64 == bobSrdr.dig  # key state updated so event was validated

        # apply msg to del's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=delKvy)
        # delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[bob].serder.diger.qb64 == bobSrdr.dig

        # now create msg with Del's delegated inception event
        sigers = delMgr.sign(ser=delSrdr.raw, verfers=verfers)

        #seal = eventing.SealSource(s="{:x}".format(bobK.sn+1),
        #d=bobSrdr.diger.qb64)

        msg = bytearray(delSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)
        counter = coring.Counter(code=coring.CtrDex.SealSourceCouples, count=1)
        msg.extend(counter.qb64b)
        seqner = coring.Seqner(sn=bobK.sn)
        msg.extend(seqner.qb64b)
        msg.extend(bobSrdr.diger.qb64b)

        assert msg == (
            b'{"v":"KERI10JSON000121_","i":"E-9tsnVcfUyXVQyBPGfntoL-xexf4Cldt_'
            b'EPzHis2W4U","s":"0","t":"dip","kt":"1","k":["DuK1x8ydpucu3480Jpd'
            b'1XBfjnCwb3dZ3x5b1CJmuUphA"],"n":"EWWkjZkZDXF74O2bOQ4H5hu4nXDlKg2'
            b'm4CBEBkUxibiU","bt":"0","b":[],"c":[],"a":[],"di":"Eta8KLf1zrE5n'
            b'-HZpgRAnDmxLASZdXEiU9u6aahqR8TI"}-AABAA2_8Guj0Gf2JoNTq7hOs4u6eOO'
            b'WhENALJWDfLxkVcS2uLh753FjtyE80lpeS3to1C9yvENyMnyN4q96ehA4exDA-GA'
            b'B0AAAAAAAAAAAAAAAAAAAAAAQE3fUycq1G-P1K1pL2OhvY6ZU-9otSa3hXiCcrxu'
            b'hjyII')

        # apply Del's delegated inception event message to Del's own Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=delKvy)
        # delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delPre in delKvy.kevers
        delK = delKvy.kevers[delPre]
        assert delK.delegated
        assert delK.serder.diger.qb64 == delSrdr.dig
        couple = delKvy.db.getAes(dbing.dgKey(delPre, delSrdr.dig))
        assert couple == seqner.qb64b + bobSrdr.diger.qb64b

        # apply Del's delegated inception event message to bob's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=bobKvy)
        # bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert delPre in bobKvy.kevers  # successfully validated
        bobDelK = bobKvy.kevers[delPre]
        assert bobDelK.delegated
        assert bobDelK.serder.diger.qb64 == delSrdr.dig  # key state updated so event was validated
        couple = bobKvy.db.getAes(dbing.dgKey(delPre, delSrdr.dig))
        assert couple == seqner.qb64b + bobSrdr.diger.qb64b

        # Setup Del rotation event assuming that Bob's next event will be an ixn delegating event
        verfers, digers, cst, nst = delMgr.rotate(pre=delPre, temp=True)

        delSrdr = eventing.deltate(
            pre=bobDelK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            dig=bobDelK.serder.diger.qb64,
            sn=bobDelK.sn + 1,
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64)

        assert delSrdr.dig == 'EPjLBcb4pp-3PGvSi_fTvLvsqUqFoJ0CVCHvIFfu93Xc'

        # Now create delegating interaction event
        seal = eventing.SealEvent(i=bobDelK.prefixer.qb64,
                                  s=delSrdr.ked["s"],
                                  d=delSrdr.dig)
        bobSrdr = eventing.interact(pre=bobK.prefixer.qb64,
                                    dig=bobK.serder.diger.qb64,
                                    sn=bobK.sn + 1,
                                    data=[seal._asdict()])

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=bobK.verfers)

        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000107_","i":"Eta8KLf1zrE5n-HZpgRAnDmxLASZdXEiU9'
            b'u6aahqR8TI","s":"2","t":"ixn","p":"E3fUycq1G-P1K1pL2OhvY6ZU-9otS'
            b'a3hXiCcrxuhjyII","a":[{"i":"E-9tsnVcfUyXVQyBPGfntoL-xexf4Cldt_EP'
            b'zHis2W4U","s":"1","d":"EPjLBcb4pp-3PGvSi_fTvLvsqUqFoJ0CVCHvIFfu9'
            b'3Xc"}]}-AABAAclMVE-bkIn-wPiAqfgR384nWmslQHQvmo2o3xQvd_4Bt6bflc4B'
            b'AmfBa03KgrDVqmB7qG2VXQbOHevkzOgRdDA')

        # apply msg to bob's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=bobKvy)
        # bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert bobK.serder.diger.qb64 == bobSrdr.dig  # key state updated so event was validated

        # apply msg to del's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=delKvy)
        # delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[bob].serder.diger.qb64 == bobSrdr.dig

        # now create msg from Del's delegated rotation event
        sigers = delMgr.sign(ser=delSrdr.raw, verfers=verfers)

        msg = bytearray(delSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)
        counter = coring.Counter(code=coring.CtrDex.SealSourceCouples, count=1)
        msg.extend(counter.qb64b)
        seqner = coring.Seqner(sn=bobK.sn)
        msg.extend(seqner.qb64b)
        msg.extend(bobSrdr.diger.qb64b)

        assert msg == (
            b'{"v":"KERI10JSON000122_","i":"E-9tsnVcfUyXVQyBPGfntoL-xexf4Cldt_'
            b'EPzHis2W4U","s":"1","t":"drt","p":"E1x1JOub6oEQkxAxTNFu1Pma6y-lr'
            b'bprNsaILHJHoPmY","kt":"1","k":["DTf6QZWoet154o9wvzeMuNhLQRr8JaAU'
            b'eiC6wjB_4_08"],"n":"E8kyiXDfkE7idwWnAZQjHbUZMz-kd_yIMH0miptIFFPo'
            b'","bt":"0","br":[],"ba":[],"a":[]}-AABAAAVUMNfOl9Fcqx-C3fAYnaxvs'
            b'iJJO3zG6rP0FQ2WVp__hMEaprrQbJL6-Esnny3U5zvMOqbso17rvecTwmVIwDw-G'
            b'AB0AAAAAAAAAAAAAAAAAAAAAAgEbOI0OIIFv2VV5bmeSq1pwCn-6b2k6TdWcCbJH'
            b'E6Ly7o')

        # apply msg to del's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=delKvy)
        # delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert bobDelK.delegated
        assert delK.serder.diger.qb64 == delSrdr.dig
        couple = delKvy.db.getAes(dbing.dgKey(delPre, delSrdr.dig))
        assert couple == seqner.qb64b + bobSrdr.diger.qb64b

        # apply Del's delegated inception event message to bob's Kevery
        parsing.Parser().parse(ims=bytearray(msg), kvy=bobKvy)
        # bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert bobDelK.delegated
        assert bobDelK.serder.diger.qb64 == delSrdr.dig  # key state updated so event was validated
        couple = delKvy.db.getAes(dbing.dgKey(delPre, delSrdr.dig))
        assert couple == seqner.qb64b + bobSrdr.diger.qb64b

        # test replay
        msgs = bytearray()
        for msg in delKvy.db.clonePreIter(pre=delPre, fn=0):
            msgs.extend(msg)
        assert len(msgs) == 1043
        assert couple in msgs

    assert not os.path.exists(delKS.path)
    assert not os.path.exists(delDB.path)
    assert not os.path.exists(bobKS.path)
    assert not os.path.exists(bobDB.path)
    """End Test"""
示例#5
0
def test_manager():
    """
    test Manager class
    """
    manager = keeping.Manager()
    assert isinstance(manager, keeping.Manager)
    assert isinstance(manager.keeper, keeping.Keeper)
    assert manager.keeper.opened

    manager.keeper.close(clear=True)
    assert not os.path.exists(manager.keeper.path)
    assert not manager.keeper.opened

    raw = b'0123456789abcdef'
    salt = coring.Salter(raw=raw).qb64
    stem = "red"

    assert salt == '0AMDEyMzQ1Njc4OWFiY2RlZg'

    ser = bytes(
        b'{"vs":"KERI10JSON0000fb_","pre":"EvEnZMhz52iTrJU8qKwtDxzmypyosgG'
        b'70m6LIjkiCdoI","sn":"0","ilk":"icp","sith":"1","keys":["DSuhyBcP'
        b'ZEZLK-fcw5tzHn2N46wRCG_ZOoeKtWTOunRA"],"nxt":"EPYuj8mq_PYYsoBKkz'
        b'X1kxSPGYBWaIya3slgCOyOtlqU","toad":"0","wits":[],"cnfg":[]}-AABA'
        b'ApYcYd1cppVg7Inh2YCslWKhUwh59TrPpIoqWxN2A38NCbTljvmBPBjSGIFDBNOv'
        b'VjHpdZlty3Hgk6ilF8pVpAQ')

    with keeping.openKS() as keeper:
        manager = keeping.Manager(keeper=keeper, salt=salt)
        assert manager.keeper.opened
        assert manager._pidx == 0
        assert manager._salt == ''  # zeroed out
        assert manager._tier == coring.Tiers.low

        # salty algorithm incept
        verfers, digers, cst, nst = manager.incept(
            salt=salt, temp=True)  # algo default salty
        assert len(verfers) == 1
        assert len(digers) == 1
        assert cst == '1'
        assert nst == '1'
        assert manager.getPidx() == 1

        spre = verfers[0].qb64b
        assert spre == b'DVG3IcCNK4lpFfpMM-9rfkY3XVUcCu5o5cxzv1lgMqxM'

        pp = json.loads(bytes(manager.keeper.getPrm(key=spre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 0
        assert pp.algo == keeping.Algos.salty
        assert pp.salt == salt
        assert pp.stem == ''
        assert pp.tier == coring.Tiers.low

        ps = json.loads(bytes(manager.keeper.getSit(key=spre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.old.pubs == []
        assert len(ps.new.pubs) == 1
        assert ps.new.pubs == ['DVG3IcCNK4lpFfpMM-9rfkY3XVUcCu5o5cxzv1lgMqxM']
        assert ps.new.ridx == 0
        assert ps.new.kidx == 0
        assert len(ps.nxt.pubs) == 1
        assert ps.nxt.pubs == ['DcHJWO4GszUP0rvVO4Tl2rUdUM1Ln5osP7BwiUeJWhdc']
        assert ps.nxt.ridx == 1
        assert ps.nxt.kidx == 1

        keys = [verfer.qb64 for verfer in verfers]
        assert keys == ps.new.pubs

        # test .pubs db
        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.new.ridx))).decode("utf-8"))
        assert pl == ps.new.pubs

        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.nxt.ridx))).decode("utf-8"))
        assert pl == ps.nxt.pubs

        digs = [diger.qb64 for diger in digers]
        assert digs == ['E8UYvbKn7KYw9e4F2DR-iduGtdA1o16ePAYjpyCYSeYo']

        oldspre = spre
        spre = b'DCu5o5cxzv1lgMqxMVG3IcCNK4lpFfpMM-9rfkY3XVUc'
        manager.move(old=oldspre, new=spre)

        # test .pubs db after move
        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.new.ridx))).decode("utf-8"))
        assert pl == ps.new.pubs

        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.nxt.ridx))).decode("utf-8"))
        assert pl == ps.nxt.pubs

        psigers = manager.sign(ser=ser, pubs=ps.new.pubs)
        for siger in psigers:
            assert isinstance(siger, coring.Siger)
        vsigers = manager.sign(ser=ser, verfers=verfers)
        psigs = [siger.qb64 for siger in psigers]
        vsigs = [siger.qb64 for siger in vsigers]
        assert psigs == vsigs
        assert psigs == [
            'AAGu9G-EJ0zrRjrDKnHszLVcwhbkSRxniDJFmB2eWcRiFzNFw1QM5GHQnmnXz385SgunZH4sLidCMyzhJWmp1IBw'
        ]

        # Test sign with indices
        indices = [3]

        # Test with pubs list
        psigers = manager.sign(ser=ser, pubs=ps.new.pubs, indices=indices)
        for siger in psigers:
            assert isinstance(siger, coring.Siger)
        assert psigers[0].index == indices[0]
        psigs = [siger.qb64 for siger in psigers]
        assert psigs == [
            'ADGu9G-EJ0zrRjrDKnHszLVcwhbkSRxniDJFmB2eWcRiFzNFw1QM5GHQnmnXz385SgunZH4sLidCMyzhJWmp1IBw'
        ]

        # Test with verfers list
        vsigers = manager.sign(ser=ser, verfers=verfers, indices=indices)
        for siger in vsigers:
            assert isinstance(siger, coring.Siger)
        assert psigers[0].index == indices[0]
        vsigs = [siger.qb64 for siger in vsigers]
        assert vsigs == psigs

        pcigars = manager.sign(ser=ser, pubs=ps.new.pubs, indexed=False)
        for cigar in pcigars:
            assert isinstance(cigar, coring.Cigar)
        vcigars = manager.sign(ser=ser, verfers=verfers, indexed=False)
        psigs = [cigar.qb64 for cigar in pcigars]
        vsigs = [cigar.qb64 for cigar in vcigars]
        assert psigs == vsigs
        assert psigs == [
            '0BGu9G-EJ0zrRjrDKnHszLVcwhbkSRxniDJFmB2eWcRiFzNFw1QM5GHQnmnXz385SgunZH4sLidCMyzhJWmp1IBw'
        ]

        # salty algorithm rotate
        oldpubs = [verfer.qb64 for verfer in verfers]
        verfers, digers, cst, nst = manager.rotate(pre=spre.decode("utf-8"))
        assert len(verfers) == 1
        assert len(digers) == 1
        assert cst == '1'
        assert nst == '1'

        pp = json.loads(bytes(manager.keeper.getPrm(key=spre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 0
        assert pp.algo == keeping.Algos.salty
        assert pp.salt == salt
        assert pp.stem == ''
        assert pp.tier == coring.Tiers.low

        ps = json.loads(bytes(manager.keeper.getSit(key=spre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.old.pubs == ['DVG3IcCNK4lpFfpMM-9rfkY3XVUcCu5o5cxzv1lgMqxM']
        assert len(ps.new.pubs) == 1
        assert ps.new.pubs == ['DcHJWO4GszUP0rvVO4Tl2rUdUM1Ln5osP7BwiUeJWhdc']
        assert ps.new.ridx == 1
        assert ps.new.kidx == 1
        assert len(ps.nxt.pubs) == 1
        assert ps.nxt.pubs == ['DRpGly44ejh01ur4ltL_LVrYcyqVCQyVLJnqWrVa57Yc']
        assert ps.nxt.ridx == 2
        assert ps.nxt.kidx == 2

        keys = [verfer.qb64 for verfer in verfers]
        assert keys == ps.new.pubs

        digs = [diger.qb64 for diger in digers]
        assert digs == ['EJUzDm_HbdIZDp94OlIoZH1gcaSdWLZhJwqKz2rVJZrc']

        assert oldpubs == ps.old.pubs

        # salty algorithm rotate
        oldpubs = [verfer.qb64 for verfer in verfers]
        deadpubs = ps.old.pubs

        verfers, digers, cst, nst = manager.rotate(pre=spre.decode("utf-8"))
        assert cst == '1'
        assert nst == '1'
        pp = json.loads(bytes(manager.keeper.getPrm(key=spre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 0

        ps = json.loads(bytes(manager.keeper.getSit(key=spre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)

        assert oldpubs == ps.old.pubs

        for pub in deadpubs:
            assert not manager.keeper.getPri(key=pub.encode("utf-8"))

        # test .pubs db
        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.new.ridx))).decode("utf-8"))
        assert pl == ps.new.pubs

        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(spre, ps.nxt.ridx))).decode("utf-8"))
        assert pl == ps.nxt.pubs

        # salty algorithm rotate to null
        verfers, digers, cst, nst = manager.rotate(pre=spre.decode("utf-8"),
                                                   count=0)
        assert cst == '1'
        assert nst == '0'

        pp = json.loads(bytes(manager.keeper.getPrm(key=spre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 0

        ps = json.loads(bytes(manager.keeper.getSit(key=spre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)

        assert digers == []
        assert ps.nxt.pubs == []

        #  attempt to rotate after null
        with pytest.raises(ValueError) as ex:  # attempt to reincept same pre
            verfers, digers, cst, nst = manager.rotate(
                pre=spre.decode("utf-8"))
        assert ex.value.args[0].startswith(
            'Attempt to rotate nontransferable ')

        # randy algo incept
        verfers, digers, cst, nst = manager.incept(algo=keeping.Algos.randy)
        assert len(verfers) == 1
        assert len(digers) == 1
        assert cst == '1'
        assert nst == '1'
        assert manager.getPidx() == 2
        rpre = verfers[0].qb64b

        pp = json.loads(bytes(manager.keeper.getPrm(key=rpre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 1
        assert pp.algo == keeping.Algos.randy
        assert pp.salt == ''
        assert pp.stem == ''
        assert pp.tier == ''

        ps = json.loads(bytes(manager.keeper.getSit(key=rpre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.old.pubs == []
        assert len(ps.new.pubs) == 1
        assert ps.new.ridx == 0
        assert ps.new.kidx == 0
        assert len(ps.nxt.pubs) == 1
        assert ps.nxt.ridx == 1
        assert ps.nxt.kidx == 1

        keys = [verfer.qb64 for verfer in verfers]
        for key in keys:
            val = bytes(manager.keeper.getPri(key.encode("utf-8")))

        digs = [diger.qb64 for diger in digers]
        assert len(digs) == 1

        oldrpre = rpre
        rpre = b'DMqxMVG3IcCNK4lpFfCu5o5cxzv1lgpMM-9rfkY3XVUc'
        manager.move(old=oldrpre, new=rpre)

        # randy algorithm rotate
        oldpubs = [verfer.qb64 for verfer in verfers]

        verfers, digers, cst, nst = manager.rotate(pre=rpre.decode("utf-8"))
        assert cst == '1'
        assert nst == '1'

        pp = json.loads(bytes(manager.keeper.getPrm(key=rpre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 1

        ps = json.loads(bytes(manager.keeper.getSit(key=rpre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)

        assert oldpubs == ps.old.pubs

        # randy algo incept with null nxt
        verfers, digers, cst, nst = manager.incept(algo=keeping.Algos.randy,
                                                   ncount=0)
        assert manager.getPidx() == 3
        rpre = verfers[0].qb64b
        assert cst == '1'
        assert nst == '0'

        pp = json.loads(bytes(manager.keeper.getPrm(key=rpre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 2

        ps = json.loads(bytes(manager.keeper.getSit(key=rpre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)

        assert digers == []
        assert ps.nxt.pubs == []

        #  attempt to rotate after null
        with pytest.raises(ValueError) as ex:  # attempt to reincept same pre
            verfers, digers, cst, nst = manager.rotate(
                pre=rpre.decode("utf-8"))

        # salty algorithm incept with stem
        verfers, digers, cst, nst = manager.incept(
            salt=salt, stem=stem, temp=True)  # algo default salty
        assert len(verfers) == 1
        assert len(digers) == 1
        assert cst == '1'
        assert nst == '1'
        assert manager.getPidx() == 4

        spre = verfers[0].qb64b
        assert spre == b'D627iBfehzh966wPzBYjKQuGOSmIkdcR7b14nZv_ULIw'

        pp = json.loads(bytes(manager.keeper.getPrm(key=spre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 3
        assert pp.algo == keeping.Algos.salty
        assert pp.salt == salt
        assert pp.stem == stem == 'red'
        assert pp.tier == coring.Tiers.low

        ps = json.loads(bytes(manager.keeper.getSit(key=spre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.old.pubs == []
        assert len(ps.new.pubs) == 1
        assert ps.new.pubs == ['D627iBfehzh966wPzBYjKQuGOSmIkdcR7b14nZv_ULIw']
        assert ps.new.ridx == 0
        assert ps.new.kidx == 0
        assert len(ps.nxt.pubs) == 1
        assert ps.nxt.pubs == ['DHNnq96NI0Bmle_VINGcgX8_VSpxbl3am7ZT6_66Fe8Q']
        assert ps.nxt.ridx == 1
        assert ps.nxt.kidx == 1

        keys = [verfer.qb64 for verfer in verfers]
        assert keys == ps.new.pubs

        digs = [diger.qb64 for diger in digers]
        assert digs == ['EAQ7QvfBLj0OrGTqzJZGutLJowUht_zBA6213agRQ8hA']

        #  attempt to reincept same first pub
        with pytest.raises(ValueError) as ex:  # attempt to reincept same pre
            verfers, digers, cst, nst = manager.incept(salt=salt,
                                                       stem=stem,
                                                       temp=True)
        assert ex.value.args[0].startswith('Already incepted pre')

        oldspre = spre
        spre = b'DCNK4lpFfpMM-9rfkY3XVUcCu5o5cxzv1lgMqxMVG3Ic'
        manager.move(old=oldspre, new=spre)

        #  attempt to reincept same first pub after move pre
        with pytest.raises(ValueError) as ex:  # attempt to reincept same pre
            verfers, digers, cst, nst = manager.incept(salt=salt,
                                                       stem=stem,
                                                       temp=True)
        assert ex.value.args[0].startswith('Already incepted pre')

        # Create nontransferable keys that are nontransferable identifier prefixes
        verfers, digers, cst, nst = manager.incept(ncount=0,
                                                   salt=salt,
                                                   stem="wit0",
                                                   transferable=False,
                                                   temp=True)
        assert cst == '1'
        assert nst == '0'
        wit0pre = verfers[0].qb64
        assert verfers[
            0].qb64 == 'B5M0jhHM3vTo15w12pOUYRwxJNaIVS96wSqbFZH-inyc'
        assert verfers[0].code == coring.MtrDex.Ed25519N
        assert not digers

        verfers, digers, cst, nst = manager.incept(ncount=0,
                                                   salt=salt,
                                                   stem="wit1",
                                                   transferable=False,
                                                   temp=True)
        assert cst == '1'
        assert nst == '0'
        wit1pre = verfers[0].qb64
        assert verfers[
            0].qb64 == 'BAH_nE1cfiGjEMK0Ac8U8N51npjBOjyZt3D-_QA4c4y0'
        assert verfers[0].code == coring.MtrDex.Ed25519N
        assert not digers

        assert wit0pre != wit1pre

        # test .ingest of sequences of keys
        secrecies = [
            ['ArwXoACJgOleVZ2PY7kXn7rA0II0mHYDhc6WrBH8fDAc'],
            ['A6zz7M08-HQSFq92sJ8KJOT2cZ47x7pXFQLPB0pckB3Q'],
            ['AcwFTk-wgk3ZT2buPRIbK-zxgPx-TKbaegQvPEivN90Y'],
            ['Alntkt3u6dDgiQxTATr01dy8M72uuaZEf9eTdM-70Gk8'],
            ['A1-QxDkso9-MR1A8rZz_Naw6fgaAtayda8hrbkRVVu1E'],
            ['AKuYMe09COczwf2nIoD5AE119n7GLFOVFlNLxZcKuswc'],
            ['AxFfJTcSuEE11FINfXMqWttkZGnUZ8KaREhrnyAXTsjw'],
            ['ALq-w1UKkdrppwZzGTtz4PWYEeWm0-sDHzOv5sq96xJY'],
        ]

        pidx, rsalt, rtier = manager.setup()  #  verify current state
        assert pidx == 6
        assert rsalt == salt == '0AMDEyMzQ1Njc4OWFiY2RlZg'
        assert rtier == coring.Tiers.low
        verferies, digers = manager.ingest(secrecies=secrecies)
        publicies = []
        for verfers in verferies:
            publicies.append([verfer.qb64 for verfer in verfers])
        assert publicies == [['DSuhyBcPZEZLK-fcw5tzHn2N46wRCG_ZOoeKtWTOunRA'],
                             ['DVcuJOOJF1IE8svqEtrSuyQjGTd2HhfAkt9y2QkUtFJI'],
                             ['DT1iAhBWCkvChxNWsby2J0pJyxBIxbAtbLA0Ljx-Grh8'],
                             ['DKPE5eeJRzkRTMOoRGVd2m18o8fLqM2j9kaxLhV3x8AQ'],
                             ['D1kcBE7h0ImWW6_Sp7MQxGYSshZZz6XM7OiUE5DXm0dU'],
                             ['D4JDgo3WNSUpt-NG14Ni31_GCmrU0r38yo7kgDuyGkQM'],
                             ['DVjWcaNX2gCkHOjk6rkmqPBCxkRCqwIJ-3OjdYmMwxf4'],
                             ['DT1nEDepd6CSAMCE7NY_jlLdG6_mKUlKS_mW-2HJY1hg']]

        ipre = publicies[0][0]

        # test .pris db
        for i, pubs in enumerate(publicies):
            pri0 = bytes(manager.keeper.getPri(key=pubs[0]))
            assert pri0.decode("utf-8") == secrecies[i][0]
            for pub in pubs:
                pri = bytes(manager.keeper.getPri(key=pub))
                assert pri

        pp = json.loads(bytes(manager.keeper.getPrm(key=ipre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 6

        assert manager.getPidx() == 7

        ps = json.loads(bytes(manager.keeper.getSit(key=ipre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.new.ridx == 7
        assert ps.new.pubs == publicies[ps.new.ridx]

        # test .pubs db
        for i, pubs in enumerate(publicies):
            pl = json.loads(
                bytes(manager.keeper.getPubs(
                    key=keeping.riKey(ipre, i))).decode("utf-8"))
            assert pl == pubs

        #  nxt pubs
        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(ipre, i + 1))).decode("utf-8"))
        assert pl

        assert [diger.qb64 for diger in digers
                ] == ['Ewt_7B0gfSE7DnMtmNEHiy8BGPVw5at2-e_JgJ1jAfEc']

        for i in range(len(publicies)):
            verfers, digers, cst, nst = manager.replay(ipre, i)
            assert verfers[0].qb64 == publicies[i][0]
            assert digers
            assert cst == nst == '1'

        with pytest.raises(IndexError):  # Test end of replay
            verfers, digers = manager.replay(ipre, i + 1)

        with pytest.raises(ValueError):  # Test past end of replay
            verfers, digers = manager.replay(ipre, i + 2)

        # test .ingest multi-sig of sequences of keys
        secrecies = [[
            'AgjD4nRlycmM5cPcAkfOATAp8wVldRsnc9f1tiwctXlw',
            'AKUotEE0eAheKdDJh9QvNmSEmO_bjIav8V_GmctGpuCQ',
            'AK-nVhMMJciMPvmF5VZE_9H-nhrgng9aJWf7_UHPtRNM'
        ], ['AT2cx-P5YUjIw_SLCHQ0pqoBWGk9s4N1brD-4pD_ANbs'],
                     [
                         'Ap5waegfnuP6ezC18w7jQiPyQwYYsp9Yv9rYMlKAYL8k',
                         'Aqlc_FWWrxpxCo7R12uIz_Y2pHUH2prHx1kjghPa8jT8',
                         'AagumsL8FeGES7tYcnr_5oN6qcwJzZfLKxoniKUpG4qc'
                     ], ['ADW3o9m3udwEf0aoOdZLLJdf1aylokP0lwwI_M2J9h0s']]

        pidx, rsalt, rtier = manager.setup()  #  verify current state
        assert pidx == 7
        assert rsalt == salt == '0AMDEyMzQ1Njc4OWFiY2RlZg'
        assert rtier == coring.Tiers.low
        verferies, digers = manager.ingest(secrecies=secrecies, ncount=3)
        publicies = []
        for verfers in verferies:
            publicies.append([verfer.qb64 for verfer in verfers])
        assert publicies == [
            [
                'D8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc',
                'DbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI',
                'Dmis7BM1brr-1r4DgdO5KMcCf8AnGcUUPhZYUxprI97s'
            ], ['DfHMsSg0CJCou4erOqaJDr3OyDEikBp5QRp7HjcJGdgw'],
            [
                'DOaXCkU3Qd0oBSYxGfYtJxUbN6U7VjZiKthPHIHbzabs',
                'DLOmEabR-cYJLMrAd0HvQC4lecbF-j2r7w3UQIY3mGMQ',
                'DAIyL2yT9nU6kChGXWce8d6q07l0vBLPNImw_f9bazeQ'
            ], ['D69EflciVP9zgsihNU14Dbm2bPXoNGxKHK_BBVFMQ-YU']
        ]

        ipre = publicies[0][0]

        # test .pris db
        for i, pubs in enumerate(publicies):
            pri0 = bytes(manager.keeper.getPri(key=pubs[0]))
            assert pri0.decode("utf-8") == secrecies[i][0]
            for pub in pubs:
                pri = bytes(manager.keeper.getPri(key=pub))
                assert pri

        pp = json.loads(bytes(manager.keeper.getPrm(key=ipre)).decode("utf-8"))
        pp = helping.datify(keeping.PrePrm, pp)
        assert pp.pidx == 7

        assert manager.getPidx() == 8

        ps = json.loads(bytes(manager.keeper.getSit(key=ipre)).decode("utf-8"))
        ps = helping.datify(keeping.PreSit, ps)
        assert ps.new.ridx == 3
        assert ps.new.kidx == 7
        assert ps.new.pubs == publicies[ps.new.ridx]

        assert len(ps.nxt.pubs) == 3

        # test .pubs db
        for i, pubs in enumerate(publicies):
            pl = json.loads(
                bytes(manager.keeper.getPubs(
                    key=keeping.riKey(ipre, i))).decode("utf-8"))
            assert pl == pubs

        #  nxt pubs
        pl = json.loads(
            bytes(manager.keeper.getPubs(
                key=keeping.riKey(ipre, i + 1))).decode("utf-8"))
        assert pl

        assert [diger.qb64 for diger in digers] == [
            'E7Ch-T3dCZZ_i0u1ACi_Yv1lyyAMoQCT5ar81eUGoPYY',
            'EhwPuWbyrJRyU5HpJaoJrq04biTLWx3heNY3TvQrlbU8',
            'EJKLXis7QLnodqvtkbkTUKdciTuM-yzhEPUzS9jtxS6Y'
        ]

        for i in range(len(publicies)):
            verfers, digers, cst, nst = manager.replay(ipre, i)
            assert verfers[0].qb64 == publicies[i][0]
            assert digers

        with pytest.raises(IndexError):  # Test end of replay
            verfers, digers = manager.replay(ipre, i + 1)

        with pytest.raises(ValueError):  # Test past end of replay
            verfers, digers = manager.replay(ipre, i + 2)

    assert not os.path.exists(manager.keeper.path)
    assert not manager.keeper.opened
    """End Test"""
示例#6
0
def test_creator():
    """
    test Creator and Creatory classes
    """
    creator = keeping.Creator()
    assert isinstance(creator, keeping.Creator)
    assert creator.create() == []
    assert creator.salt == ''
    assert creator.stem == ''
    assert creator.tier == ''

    creator = keeping.RandyCreator()
    assert isinstance(creator, keeping.RandyCreator)
    assert isinstance(creator, keeping.Creator)
    assert creator.salt == ''
    assert creator.stem == ''
    assert creator.tier == ''
    signers = creator.create()
    assert len(signers) == 1
    signer = signers[0]
    assert isinstance(signer, coring.Signer)
    assert signer.code == coring.MtrDex.Ed25519_Seed
    assert signer.verfer.code == coring.MtrDex.Ed25519
    assert signer.verfer.code not in coring.CryNonTransDex

    signers = creator.create(count=2, transferable=False)
    assert len(signers) == 2
    for signer in signers:
        assert isinstance(signer, coring.Signer)
        assert signer.code == coring.MtrDex.Ed25519_Seed
        assert signer.verfer.code == coring.MtrDex.Ed25519N
        assert signer.verfer.code in coring.CryNonTransDex

    creator = keeping.SaltyCreator()
    assert isinstance(creator, keeping.SaltyCreator)
    assert isinstance(creator, keeping.Creator)
    assert isinstance(creator.salter, coring.Salter)
    assert creator.salter.code == coring.MtrDex.Salt_128
    assert creator.salt == creator.salter.qb64
    assert creator.stem == ''
    assert creator.tier == creator.salter.tier
    signers = creator.create()
    assert len(signers) == 1
    signer = signers[0]
    assert isinstance(signer, coring.Signer)
    assert signer.code == coring.MtrDex.Ed25519_Seed
    assert signer.verfer.code == coring.MtrDex.Ed25519
    assert signer.verfer.code not in coring.CryNonTransDex

    signers = creator.create(count=2, transferable=False)
    assert len(signers) == 2
    for signer in signers:
        assert isinstance(signer, coring.Signer)
        assert signer.code == coring.MtrDex.Ed25519_Seed
        assert signer.verfer.code == coring.MtrDex.Ed25519N
        assert signer.verfer.code in coring.CryNonTransDex

    raw = b'0123456789abcdef'
    salt = coring.Salter(raw=raw).qb64
    assert salt == '0AMDEyMzQ1Njc4OWFiY2RlZg'
    creator = keeping.SaltyCreator(salt=salt)
    assert isinstance(creator, keeping.SaltyCreator)
    assert isinstance(creator, keeping.Creator)
    assert isinstance(creator.salter, coring.Salter)
    assert creator.salter.code == coring.MtrDex.Salt_128
    assert creator.salter.raw == raw
    assert creator.salter.qb64 == salt
    signers = creator.create()
    assert len(signers) == 1
    signer = signers[0]
    assert isinstance(signer, coring.Signer)
    assert signer.code == coring.MtrDex.Ed25519_Seed
    assert signer.qb64 == 'A8wl7SXA6nCdf0-S9fWaHbq-XMZiXpFaBYZyVzwIBAn0'
    assert signer.verfer.code == coring.MtrDex.Ed25519
    assert signer.verfer.code not in coring.CryNonTransDex
    assert signer.verfer.qb64 == 'DxnLqpuCcrO8ITn3i1DhI-zqkgQJdNhAEfsGQLiE1jcQ'

    signers = creator.create(count=1, transferable=False, temp=True)
    assert len(signers) == 1
    signer = signers[0]
    assert isinstance(signer, coring.Signer)
    assert signer.code == coring.MtrDex.Ed25519_Seed
    assert signer.qb64 == 'AwasAzSejEulG1472bEZP7LNhKsoXAky40jgqWZKTbp4'
    assert signer.verfer.code == coring.MtrDex.Ed25519N
    assert signer.verfer.code in coring.CryNonTransDex
    assert signer.verfer.qb64 == 'BVG3IcCNK4lpFfpMM-9rfkY3XVUcCu5o5cxzv1lgMqxM'

    creator = keeping.Creatory(algo=keeping.Algos.salty).make(salt=salt)
    assert isinstance(creator, keeping.SaltyCreator)
    assert creator.salter.qb64 == salt

    creator = keeping.Creatory(algo=keeping.Algos.randy).make()
    assert isinstance(creator, keeping.RandyCreator)
    """End Test"""
示例#7
0
def test_exchanger():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64
    redSalt = coring.Salter(raw=b'abcdef0123456789').qb64

    with basing.openDB(name="sid") as sidDB, \
            keeping.openKS(name="sid") as sidKS, \
            basing.openDB(name="red") as redDB, \
            keeping.openKS(name="red") as redKS:

        limit = 1.0
        tock = 0.03125
        doist = doing.Doist(limit=limit, tock=tock)

        # Init key pair managers
        sidMgr = keeping.Manager(ks=sidKS, salt=sidSalt)

        # Init Keverys
        sidKvy = eventing.Kevery(db=sidDB)
        redHab = habbing.Habitat(ks=redKS, db=redDB, temp=True)
        redKvy = eventing.Kevery(db=redDB)

        # Setup sid by creating inception event
        verfers, digers, cst, nst = sidMgr.incept(
            stem='sid', temp=True)  # algo default salty and rooted
        sidSrdr = eventing.incept(
            keys=[verfer.qb64 for verfer in verfers],
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64,
            code=coring.MtrDex.Blake3_256)

        sidPre = sidSrdr.ked["i"]

        sidMgr.move(old=verfers[0].qb64,
                    new=sidPre)  # move key pair label to prefix

        sigers = sidMgr.sign(ser=sidSrdr.raw, verfers=verfers)

        excMsg = bytearray(sidSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        excMsg.extend(counter.qb64b)
        for siger in sigers:
            excMsg.extend(siger.qb64b)

        sidIcpMsg = excMsg  # save for later

        parsing.Parser().parse(ims=bytearray(sidIcpMsg), kvy=redKvy)
        assert redKvy.kevers[sidPre].sn == 0  # accepted event

        echo = EchoDoer(tymth=doist.tymen())
        redExc = exchanging.Exchanger(hab=redHab,
                                      tymth=doist.tymen(),
                                      handlers=[echo])

        pl = dict(x="y")
        sidExcSrdr = exchanging.exchange(route="/test/message", payload=pl)

        # Create exn message, sign it and attack Signer Seal
        sigers = sidMgr.sign(ser=sidExcSrdr.raw, verfers=verfers)

        excMsg = bytearray(sidExcSrdr.raw)
        excMsg.extend(
            coring.Counter(coring.CtrDex.SignerSealCouples, count=1).qb64b)
        excMsg.extend(sidPre.encode("utf-8"))

        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        excMsg.extend(counter.qb64b)
        for siger in sigers:
            excMsg.extend(siger.qb64b)

        parsing.Parser().parse(ims=bytearray(excMsg), kvy=redKvy, exc=redExc)

        doist.do(doers=[redExc])
        assert doist.tyme == limit

        resp = echo.cues.popleft()
        respSer = coring.Serder(raw=resp.raw)
        assert respSer.ked['t'] == coring.Ilks.exn
        assert respSer.ked['r'] == "/test/messageResp"
        assert respSer.ked['q'] == dict(req=pl)
示例#8
0
def test_replay():
    """
    Test disjoint and conjoint replay

    Deb creates series of events.
    Deb replays Deb's events to Cam and collects Cam's receipts
    Deb replays Deb's events with Cam's recepts to Bev and collects Bev's receipts
    Deb replays Deb's events with both Cam's and  Bev's receipts to Cam
    Compare replay of Deb's events with receipts by both Deb and Cam to confirm identical
    """

    with basing.openDB(name="deb") as debDB, keeping.openKS(name="deb") as debKS, \
         basing.openDB(name="cam") as camDB, keeping.openKS(name="cam") as camKS, \
         basing.openDB(name="bev") as bevDB, keeping.openKS(name="bev") as bevKS, \
         basing.openDB(name="art") as artDB, keeping.openKS(name="art") as artKS:

        # setup Deb's habitat using default salt multisig already incepts
        sith = ["1/2", "1/2", "1/2"]  # weighted signing threshold
        debHab = habbing.Habitat(name='deb',
                                 ks=debKS,
                                 db=debDB,
                                 isith=sith,
                                 icount=3,
                                 temp=True)
        assert debHab.ks == debKS
        assert debHab.db == debDB
        assert debHab.kever.prefixer.transferable

        # setup Cam's habitat using default salt multisig already incepts
        # Cam's receipts will be vrcs with 3 indexed sigantures attached
        sith = '2'  # hex str of threshold int
        camHab = habbing.Habitat(name='cam',
                                 ks=camKS,
                                 db=camDB,
                                 isith=sith,
                                 icount=3,
                                 temp=True)
        assert camHab.ks == camKS
        assert camHab.db == camDB
        assert camHab.kever.prefixer.transferable

        # setup Bev's habitat using default salt nonstransferable already incepts
        # Bev's receipts will be rcts with a receipt couple attached
        sith = '1'  # hex str of threshold int
        bevHab = habbing.Habitat(name='bev',
                                 ks=bevKS,
                                 db=bevDB,
                                 isith=sith,
                                 icount=1,
                                 transferable=False,
                                 temp=True)
        assert bevHab.ks == bevKS
        assert bevHab.db == bevDB
        assert not bevHab.kever.prefixer.transferable

        # setup Art's habitat using custom salt nonstransferable so not match Bev
        # already incepts
        # Art's receipts will be rcts with a receipt couple attached
        salt = coring.Salter(raw=b'abcdef0123456789').qb64
        sith = '1'  # hex str of threshold int
        artHab = habbing.Habitat(name='art',
                                 ks=artKS,
                                 db=artDB,
                                 isith=sith,
                                 icount=1,
                                 salt=salt,
                                 transferable=False,
                                 temp=True)
        assert artHab.ks == artKS
        assert artHab.db == artDB
        assert not artHab.kever.prefixer.transferable

        # first setup disjoint replay then conjoint replay
        # Create series of event for Deb
        debMsgs = bytearray()
        debMsgs.extend(debHab.makeOwnInception())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.rotate())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())

        assert debMsgs == (
            b'{"v":"KERI10JSON00015b_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAaf'
            b'ez-encK314","s":"0","t":"icp","kt":["1/2","1/2","1/2"],"k":["DRx'
            b'CLERO9eSvG4fluzOsK52GCWCtKOZClVwA38Oa--MA","DCxzT16ikP6LKVJfr6hv'
            b'1jmhynm6I4-KoGYkJtd9uBro","DsDl5xSHnIlcGo13u5jDRr1jJMkQ34nEc5R6N'
            b'YsdPS2k"],"n":"Eer5S019j0eEFNFLb0R0UDMoNLavlLiQ73fHGU7MUHXg","bt'
            b'":"0","b":[],"c":[],"a":[]}-AADAA4HzkCruAhoxet6Vrk_tBCwbwaT78dRw'
            b'w9RQJb0MR_tmSpEYOYDue-pBQCthsgDJzjyElpSmzNedlY-hVd6rbDwABJnfOgI6'
            b'teO_3fESnXgiz_9J_F_VfQliLWvLCM8ZnVjrryBuiMYOUmHbfXuNtRC4iZxb-RU0'
            b'lC55O0r5c5hyrAgACnZEXW7jYpAdrIfmOmH-OEHmhxcwQNu31k-mmzyNTfFvAxmp'
            b'r7-zLdmzlWKfMBlE6eAbDgCdNr_VL2l8xeJExAA{"v":"KERI10JSON000098_",'
            b'"i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"1","t":"'
            b'ixn","p":"E4gF0E1fkpEPBjeq1Sm-RK_Rvg56KOmtBHGfNe_tPxWc","a":[]}-'
            b'AADAAvo8lxVzu4YS6nG3BXu7PncYdZO57P4gYY-ikaRepVIOeRnZ10iMdJGcyULm'
            b'mdXLRaVxtuxI956cJljg3joSMBgABgHtCeHi-UZjnI1IWW9ZF8E7ni6UwerFOvPV'
            b'7z3i1pI7D3HJCoSx8XkhdXPGzUtrNuAvxVptsJtF17_-rP50bBwACguCjTA2taPP'
            b'EyhVecWjtpoBJCAiYeTdeDv3Hq0pAJXWa7SWjxlDR2-f1TIIXg8PbBD_tgn4Z6zp'
            b'LZcPLLHH5Cg{"v":"KERI10JSON000190_","i":"EeTLHxy5Npa4SQlFABzhu66'
            b'FUuSl_iJAafez-encK314","s":"2","t":"rot","p":"EYROVd3Ho83kEgBkrN'
            b'v6kqTAG4YeCqyPWYBo2jCPteiw","kt":["1/2","1/2","1/2"],"k":["Dj-DU'
            b'wfCmOrE3ijqucR0I89_fYTFbyotaqeQyDfupkEU","DL-k_8BanjLYaAdm6WWKIp'
            b'HcHwcbF834vnLPgpW1NL8k","DWG2ZFsWYUsbDI1Kmu8JH22iGaVDGvM7pnuT4y2'
            b'oR3VI"],"n":"EYd4ha92A2yttnCoLMqFGRzh6nsgduE910LD-scP7C3Q","bt":'
            b'"0","br":[],"ba":[],"a":[]}-AADAAspTV94LrwMhYVzZD0xu16aKjf1YQ8nT'
            b'Ta08ik1Fah545jAoe6n1xdnKSgL9Alucp4F-Yl69ksAttb4hTlnikDwABKspYVa4'
            b'J3r7ox-gDsPbpI5jiFSTcDCjBJGfU6hWhMXx7zpgG1jt4cTeW83oaILMbW85i_U7'
            b'RT3x6Sm2z5ytCCQACf157-iV13AXKaIddVaXexNx5K9INhJ44tfpb3OBjuPk5JMj'
            b'VGIU0iz5LkQlc_rV9D79E1pC5Z--YGplzQMv0Ag{"v":"KERI10JSON000098_",'
            b'"i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"3","t":"'
            b'ixn","p":"EA4mqdTa4RPrUJ3B_lmEPSxQK50tDkxRRVwVlLzcAdb0","a":[]}-'
            b'AADAAte_OEI-pzZulc4454QS391RR5bPndHIoLG_vLsC4Qmedqz7o04zuisW-7mr'
            b'TcfU6ZWs7rlMdSHTBZFErsY-FDQABiHkOIixpSaHGZ80--2JzhmR0TCla09WiEJH'
            b'5gTd9XXmxDfzDVON9FgDqLKf_Tf1nmgRh_eQFXu42jfvQG4Q1AAACp478kKPjbh1'
            b'pCxlmqa65PplcTa9zG4zsdYz2raYOiregvotKK30LNXm58886gSuSnEWifJvb-zY'
            b'wvdK8GsgqBg{"v":"KERI10JSON000098_","i":"EeTLHxy5Npa4SQlFABzhu66'
            b'FUuSl_iJAafez-encK314","s":"4","t":"ixn","p":"Ecw6XFmjIeMiYp1MTG'
            b'e4KRk9HnygNpnORox6AaCfC44Y","a":[]}-AADAANlbayWV5QQdCTqmh9dSEb13'
            b'stiK3srIyL9z4FWMZr_nwejoqK9j9Ic6wBQiUVksayOmGVtknUWrDNOY-PzzgBQA'
            b'B2FONMatheF144ziEB7uJpGZa3vugxedmLFfOD5CcoX7z6eX6ZZ_fIVkOHRVOxmv'
            b'nfYyVF7uC8G40PeGgkh5eCAACSwyvmjZcik1VBQCCfh5Mq2SQLUvVfFg9plIanMR'
            b'Trp7bG_OXE5SSqou6VFNon3Ub8IlBA90-dR7DRRDNPQ5UBw{"v":"KERI10JSON0'
            b'00098_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"'
            b'5","t":"ixn","p":"EQW9ROsIuNEdKu_ZIm9zDPKIVallegMHz2PVygiZgttc",'
            b'"a":[]}-AADAAtjUR1rNouk9T92o22qUbNvptIEjrnqKU3eJTiwdDGoWIwhTLY1T'
            b'UunYYpqtbk55oaCyc_MXkP-6l57YDiOAsCwAB5Fl7CZj1P1-NsYgrf2caXvWTfkg'
            b'u15C61JRuRpDnjTtevCjxspLQw6hxeJ6-2mTZHqIHC3hzW01Ed2mFOC_eDAACV87'
            b'jI4scXXRlNfqXmRrsivc0p3vBIO1OLNC6fex-bFbwV6U8zd_pjWTDZLwCnDm3KJq'
            b'labzAfGxX32trskGpCQ{"v":"KERI10JSON000098_","i":"EeTLHxy5Npa4SQl'
            b'FABzhu66FUuSl_iJAafez-encK314","s":"6","t":"ixn","p":"E52dhrHeFM'
            b'AYWsROU3fPEmD8pCsO_Q2MfvLuZufX43o0","a":[]}-AADAAVe6bfQeaR2X8UIB'
            b'OS1HMVLWho7FETQ17FQly0USMiSVDIWh8KTEeW-ndMDUlDBBeNEf3UiwDIRE62-k'
            b'ICoofAwABk4ndaxtTYTLmlxWM2Qb38RYtwSRzr7KRRbhLmL_zLXa7KnoAkmCa9LL'
            b'ZT5o_6rNjuFruYo7eSL4JfFhCEEn_CwACdPvsbvEV30PaDhbDmdVqI9fzGOSp34e'
            b'oTChNPt_UGq3uvCAAlwJa66g4WndLiTkN_BmKZP8YCgn40mUj5TFnAQ')

        # Play debMsgs to Cam
        # create non-local kevery for Cam to process msgs from Deb
        camKevery = eventing.Kevery(db=camHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(debMsgs), kvy=camKevery)
        # camKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in camKevery.kevers
        assert camKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(camKevery.cues) == 7

        # get disjoints receipts (vrcs) from Cam of Deb's events by processing Cam's cues
        camMsgs = camHab.processCues(camKevery.cues)
        assert camMsgs == (
            b'{"v":"KERI10JSON00014b_","i":"EnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ'
            b'9KYr-ZdNMg","s":"0","t":"icp","kt":"2","k":["DJBtEHHnzNtE-zxH1xe'
            b'X4wxs9rEfUQ8d1ancgJJ1BLKk","DMu6yPITjrOBoTPfsY-r1Rc0ead8GKmoCxA_'
            b'BugKehgY","DfhpvbNyYu1fxTBTXy8eCgghMcOYnxkgoGPBr0ZBZPQA"],"n":"E'
            b'J85AI0se7UiFBFL1Vl80PnmQ-0dU6q_NXCh6BlSJcKg","bt":"0","b":[],"c"'
            b':[],"a":[]}-AADAAya98TxjoKqXBaXKBKmu0_98hrOSjoq8YeT5HlKBZsBvGPGU'
            b'NE3Ex9lkhLTl-U_Gx_1JLqEYJJaVrGLaArb5pDAABiYDraSegcRyxe8Syrd3uYqN'
            b'HTcalW-_hgVqsUDEZcqdsbje2fBxHO4blsODaSDMm2Crvdj5uvaLch-svOBdEDgA'
            b'CVGMTILr9hF9NHVscjqi5yCvtkwMhtZHEqh_6v7N_flmXKCkN2AXAi9OEmf-pdXj'
            b'0UlLdab6MkOfbxSRsmrjTDQ{"v":"KERI10JSON000091_","i":"EeTLHxy5Npa'
            b'4SQlFABzhu66FUuSl_iJAafez-encK314","s":"0","t":"rct","d":"E4gF0E'
            b'1fkpEPBjeq1Sm-RK_Rvg56KOmtBHGfNe_tPxWc"}-FABEnjQHu6cA7Mk4gdlnSbh'
            b'aKtjOh23I2_1ZZ9KYr-ZdNMg0AAAAAAAAAAAAAAAAAAAAAAAEZdlVoasgQzvn7mj'
            b'ai5hTX7JgLyHrRkeo8Mf5SXL10ro-AADAAY7ru97WNltKYXVBeiqSQ2JhCU6W6Uv'
            b'wSmYQRNAQ7Vk3_VslqnAkQDApZwVY-I5nonPybqxS4riBoN8O2MvH3BwABNvm83-'
            b'pYo3WR7BAtg13vvHsaX2PfSZn7ajBCRzUXaQ0ZLNr0wJddMywcVtOrgY0myRmiNq'
            b'YvetEkb0PJwQG4AwACjit5HUQSAeEMyfC5GeAsPHsGqLwbYMJdqxuZrnzfE2xtXe'
            b'3dEz9iSKEFUbykO0f1ThpMLpjat3SsNtZUtn07CQ{"v":"KERI10JSON000091_"'
            b',"i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"1","t":'
            b'"rct","d":"EYROVd3Ho83kEgBkrNv6kqTAG4YeCqyPWYBo2jCPteiw"}-FABEnj'
            b'QHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ9KYr-ZdNMg0AAAAAAAAAAAAAAAAAAAAAA'
            b'AEZdlVoasgQzvn7mjai5hTX7JgLyHrRkeo8Mf5SXL10ro-AADAAx2QNu8staqEHq'
            b'lv3z__tb9wPPuwTqF3uicXv5BAr3npLW541r9RKcDUQ1yMk1TWcs1vO2a_L2rwtC'
            b'h_pP8kzAgABk1B6jf72NOLhSIbAXTbM5JhxiFatklzqYCkiQw12jGxNOHxmEuKNF'
            b'0IatvNc3m96hcOb7dc2ZOIQGxX9Ud9nCwAC9LGHfopCtAgtC7OK-aOfYQXN36_Ll'
            b'RHZu3eeT9E_pFG9I0LYfoRNf0hGVcyPRBpqrIVOTkH1NBWRbVyOMSYhDA{"v":"K'
            b'ERI10JSON000091_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK'
            b'314","s":"2","t":"rct","d":"EA4mqdTa4RPrUJ3B_lmEPSxQK50tDkxRRVwV'
            b'lLzcAdb0"}-FABEnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ9KYr-ZdNMg0AAAAA'
            b'AAAAAAAAAAAAAAAAAAEZdlVoasgQzvn7mjai5hTX7JgLyHrRkeo8Mf5SXL10ro-A'
            b'ADAAmMLDAvNgoQ_hnYEfx6uzg0LzRuODZmgwhou-EZv83BNJ9JwNabG9oSuLL15Z'
            b'Zc0blUm8GJ0BJuBcE4rjNW3-CAABlkXt_qnbOaBjqlfNXbLxZ_Rx2SCy8pVSYSz7'
            b'-UbB2lHpIfGMApVcTamn4pYhyOnaEVVO47tWZ3vDmXkf3WrKBQAC4MZmfqt3B9SY'
            b'DROZk8shO6vWxzHfZVBzLtNZAJrJLq8FoZ66q3bG4Pgn1pc0ID0fjkpXSiR5aOF2'
            b'2QhT06erDA{"v":"KERI10JSON000091_","i":"EeTLHxy5Npa4SQlFABzhu66F'
            b'UuSl_iJAafez-encK314","s":"3","t":"rct","d":"Ecw6XFmjIeMiYp1MTGe'
            b'4KRk9HnygNpnORox6AaCfC44Y"}-FABEnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1Z'
            b'Z9KYr-ZdNMg0AAAAAAAAAAAAAAAAAAAAAAAEZdlVoasgQzvn7mjai5hTX7JgLyHr'
            b'Rkeo8Mf5SXL10ro-AADAASQpD32fjD-IJuz9w1CFLXYtHE-9rtVRqSvQPqT8yjHO'
            b'lKMNG2apDa___svlQSw_OmgsCB-LzQn7dyyv73w3KCQABcbrlJRw3GaM5l5NCq_7'
            b'czfZBAyXPwvpfjwM3BAMnt-tDmTEoJku4MpruiwpgSWcPw_Xp3SE3nmxPIK6-Q08'
            b'aCAAC58Bw2io7IEt3ZvfEdaHns97Y4QGCnFovmz9VFfp3c2Mjioa1sDgOf9uybHV'
            b'MKBhpsUy2_BfpgkVOhmcY6GtzCw{"v":"KERI10JSON000091_","i":"EeTLHxy'
            b'5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"4","t":"rct","d":"EQ'
            b'W9ROsIuNEdKu_ZIm9zDPKIVallegMHz2PVygiZgttc"}-FABEnjQHu6cA7Mk4gdl'
            b'nSbhaKtjOh23I2_1ZZ9KYr-ZdNMg0AAAAAAAAAAAAAAAAAAAAAAAEZdlVoasgQzv'
            b'n7mjai5hTX7JgLyHrRkeo8Mf5SXL10ro-AADAAsW_khBjW_8JTAMqSmfO719vBlr'
            b'NVpJu-8bpboWZm8hhYfKEEfUWC40GWoYwSN_Xk-2v6oPVp4_oHVVB4hMavAAABuR'
            b'VEC014QaDOacru4RchNJBZCa5jKhfK10vt-Mb88mQY-HF-kVywqvGnkFyCZowKPz'
            b'sLEJbTAa8py3hCKJ-5AQACo4tT9i1sv7JM6zhprqwklVnYKsG6Y1DCfGj6c6vIWz'
            b'StZeO_ICz9iOZkB8IuwJp8r5AYgqJlNl8cl93sgknZDw{"v":"KERI10JSON0000'
            b'91_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"5",'
            b'"t":"rct","d":"E52dhrHeFMAYWsROU3fPEmD8pCsO_Q2MfvLuZufX43o0"}-FA'
            b'BEnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ9KYr-ZdNMg0AAAAAAAAAAAAAAAAAA'
            b'AAAAAEZdlVoasgQzvn7mjai5hTX7JgLyHrRkeo8Mf5SXL10ro-AADAA_06qSZGjm'
            b'75-wLDLPBK-p32mM1oeDQAQD2wfdQ75jn-JRkYqGztS2tQDBFlxK4uiceok50-ZJ'
            b'f64An_oB649AQABZpuMeCzUi0oF98kXROI94G3cWLVrDVdbvxDNe60uE7rQ-qwDq'
            b'tErr65hMaCgbTO3zD9aumRQMU5-1uWZrIxWDQACyukFA_3zKJQyctI3JER5XO8r_'
            b'iz9Ga5CXxnZFqSuGmQqQEpA9wMDOZ66hRBRNgImMQh-btX4sqbjO_ycaGmjBg{"v'
            b'":"KERI10JSON000091_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-'
            b'encK314","s":"6","t":"rct","d":"ENsvgXw3H4VhL3i-eONdu7tgarzrgm9z'
            b'c2Lj3XlwZ2_4"}-FABEnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ9KYr-ZdNMg0A'
            b'AAAAAAAAAAAAAAAAAAAAAAEZdlVoasgQzvn7mjai5hTX7JgLyHrRkeo8Mf5SXL10'
            b'ro-AADAAEjRuwX1j8xEYIXjf1cmhLpmF4IwKBGU2fvL0rbbBMN4bA4VTtnAqo6Nh'
            b'GYK4XKKVL_SKLaL9x9PcFc5ykBqsBwABVwlNGkdx_oScxgYzhLMDmAi-Ro5n85ly'
            b'LRI6DdtMIRfpgyIa2pPw1BkA2FmmsUkkwdTWxNq77AyfbcQzDKOzDAACSIxniS9R'
            b'7dsM11Q8uD5qSAxcGyF-CUNYT7NZmQdL52MnszSYy7Mvpwnq9L842jNgL_G8zqif'
            b'0eizybIVsQj7AQ')

        # Play camMsgs to Deb
        # create non-local kevery for Deb to process msgs from Cam
        debKevery = eventing.Kevery(db=debHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(camMsgs), kvy=debKevery)
        # debKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in debKevery.kevers
        assert debKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Cam's events by processing Deb's cues
        debCamVrcs = debHab.processCues(debKevery.cues)
        assert debCamVrcs == (
            b'{"v":"KERI10JSON000091_","i":"EnjQHu6cA7Mk4gdlnSbhaKtjOh23I2_1ZZ'
            b'9KYr-ZdNMg","s":"0","t":"rct","d":"EZdlVoasgQzvn7mjai5hTX7JgLyHr'
            b'Rkeo8Mf5SXL10ro"}-FABEeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK31'
            b'40AAAAAAAAAAAAAAAAAAAAAAgEA4mqdTa4RPrUJ3B_lmEPSxQK50tDkxRRVwVlLz'
            b'cAdb0-AADAARwO4P3VantEgLrBs4K7hvStQ_kpN5EiFjklROGNkV19PBtxO0uUU8'
            b'0RDbWBjuUgIm59v9oJQKe-hdS8neEI2CgABAptixkGIj7UX1PU9Vlr1kZexUaIie'
            b'AugElzH99gCfQG2MMtOb3EO5ybgMHkWKKr7PaTpi4H2XrQ-me-PT_fGAgACSUTaW'
            b'0o0XhD0bQn-Qv2TwDj01L8zRyy7dqlGemZSzl2DBnliA_NqGHBQ2QJKIZfuIc6Mc'
            b'c3n_HpqI6s7xt-jCQ')

        # Play disjoints debCamVrcs to Cam
        parsing.Parser().parseOne(ims=bytearray(debCamVrcs), kvy=camKevery)
        # camKevery.processOne(ims=bytearray(debCamVrcs))  # give copy to process

        # Play debMsgs to Bev
        # create non-local kevery for Bev to process msgs from Deb
        bevKevery = eventing.Kevery(db=bevHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(debMsgs), kvy=bevKevery)
        # bevKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in bevKevery.kevers
        assert bevKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(bevKevery.cues) == 7

        # get disjoints receipts (rcts) from Bev of Deb's events by processing Bevs's cues
        bevMsgs = bevHab.processCues(bevKevery.cues)
        assert bevMsgs == (
            b'{"v":"KERI10JSON0000c1_","i":"BCqmHiYBZx_uaQiCTVeum-vt1ZPti8chqb'
            b'-GpQBPaurA","s":"0","t":"icp","kt":"1","k":["BCqmHiYBZx_uaQiCTVe'
            b'um-vt1ZPti8chqb-GpQBPaurA"],"n":"","bt":"0","b":[],"c":[],"a":[]'
            b'}-AABAAgO3RAPPeeFcl5ZvoIR55jsqjQsfKQNenz9EUITRBtu9Q5Js-Umzd_mvSq'
            b'ZymNJnwLL656s7P-hTZRtG-8-rhBg{"v":"KERI10JSON000091_","i":"EeTLH'
            b'xy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"0","t":"rct","d":"'
            b'E4gF0E1fkpEPBjeq1Sm-RK_Rvg56KOmtBHGfNe_tPxWc"}-CABBCqmHiYBZx_uaQ'
            b'iCTVeum-vt1ZPti8chqb-GpQBPaurA0B0VYuHkBtlKSqsXj_0-2mSNzQ9UOiO-iX'
            b'jG4V74ivokdt9GUYh5OnZ-lW-SfyzGhQv6QlPRcy7nWTyi_mMzOCAg{"v":"KERI'
            b'10JSON000091_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314'
            b'","s":"1","t":"rct","d":"EYROVd3Ho83kEgBkrNv6kqTAG4YeCqyPWYBo2jC'
            b'Pteiw"}-CABBCqmHiYBZx_uaQiCTVeum-vt1ZPti8chqb-GpQBPaurA0B_gS89Rl'
            b'Y4y-YTTgBpjdBiA6l8PbGZkd4ODmA3RQyDGVapnpMB_SLvolQuz7WxyE0NsnpJ-D'
            b'nVFTt-Dv-dKGADA{"v":"KERI10JSON000091_","i":"EeTLHxy5Npa4SQlFABz'
            b'hu66FUuSl_iJAafez-encK314","s":"2","t":"rct","d":"EA4mqdTa4RPrUJ'
            b'3B_lmEPSxQK50tDkxRRVwVlLzcAdb0"}-CABBCqmHiYBZx_uaQiCTVeum-vt1ZPt'
            b'i8chqb-GpQBPaurA0BcbCV4kKek9oab8MDhzvzf0ucYnTIzNiWHLNh65mpxUa2XL'
            b'jrEfbWlrjpiDXTyYShlLNt8fZxnnwoAW4aelTyBA{"v":"KERI10JSON000091_"'
            b',"i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"3","t":'
            b'"rct","d":"Ecw6XFmjIeMiYp1MTGe4KRk9HnygNpnORox6AaCfC44Y"}-CABBCq'
            b'mHiYBZx_uaQiCTVeum-vt1ZPti8chqb-GpQBPaurA0BZSz6DBrS702RsSJ2qhp5V'
            b'_4UG3u4v9_PZUxZqkTnBmkxkX-dA9Ml5c_2YaZ0_ETfhrbq30r1elT4gXhKJbRAA'
            b'A{"v":"KERI10JSON000091_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAa'
            b'fez-encK314","s":"4","t":"rct","d":"EQW9ROsIuNEdKu_ZIm9zDPKIVall'
            b'egMHz2PVygiZgttc"}-CABBCqmHiYBZx_uaQiCTVeum-vt1ZPti8chqb-GpQBPau'
            b'rA0BFvLdsWHk5oGOZQCnDEVww3dMlXZYo9JzNbuJUdK0IqWaJAQBIMEKOqLvZzMx'
            b'FIi6xNmJCQYKFu5328ovxtddCg{"v":"KERI10JSON000091_","i":"EeTLHxy5'
            b'Npa4SQlFABzhu66FUuSl_iJAafez-encK314","s":"5","t":"rct","d":"E52'
            b'dhrHeFMAYWsROU3fPEmD8pCsO_Q2MfvLuZufX43o0"}-CABBCqmHiYBZx_uaQiCT'
            b'Veum-vt1ZPti8chqb-GpQBPaurA0BDaF78ajVz3FOsApq_1iBTK2i1PT8F0Fgz4q'
            b'r4HuboYf5XMWR8IvrYcYvthaaRP5168Ge-npP6UgRUd7t8vwCDw{"v":"KERI10J'
            b'SON000091_","i":"EeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK314","'
            b's":"6","t":"rct","d":"ENsvgXw3H4VhL3i-eONdu7tgarzrgm9zc2Lj3XlwZ2'
            b'_4"}-CABBCqmHiYBZx_uaQiCTVeum-vt1ZPti8chqb-GpQBPaurA0B9TkOKxh1bS'
            b'1gwzpNCx5R-AW0D_xHbbBNlVSdyPW4VUJm4PvRCK9UFsHHk2LGv0KbqRe7ftiY6o'
            b'V7hSkY4rfGAw')

        # Play bevMsgs to Deb
        parsing.Parser().parse(ims=bytearray(bevMsgs), kvy=debKevery)
        # debKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in debKevery.kevers
        assert debKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Bev's events by processing Deb's cues
        debBevVrcs = debHab.processCues(debKevery.cues)
        assert debBevVrcs == (
            b'{"v":"KERI10JSON000091_","i":"BCqmHiYBZx_uaQiCTVeum-vt1ZPti8chqb'
            b'-GpQBPaurA","s":"0","t":"rct","d":"ERejsDJsBCs9b2j0Cd3pIDxNoGEw8'
            b'zQd94AXMduyyIF8"}-FABEeTLHxy5Npa4SQlFABzhu66FUuSl_iJAafez-encK31'
            b'40AAAAAAAAAAAAAAAAAAAAAAgEA4mqdTa4RPrUJ3B_lmEPSxQK50tDkxRRVwVlLz'
            b'cAdb0-AADAApoGcQmhmFQ2tQmovG0aZNxBN3QMgynKdfVA3pNyJQ-UMBnliFkeaC'
            b'gioFRXuH9SLm3R1XlFjmIJNvZ7hoJ3bBQABLKipRIasV9TRzcoGF7sQs9vfkcneF'
            b'7y1YqKMw9oWKEzhJKMuk0QUz6E1fse8mUDazKQsXqY1uKnSFhfjuqAhBQACFrF4i'
            b'Nt4Cm0srlq1QsXwJe3duzNKOEdf4z-WxWSw49dDpYyfllWEIs8Eu65IADEycjZR3'
            b'q9BTeO9QARuieV_Dw')

        # Play disjoints debBevVrcs to Bev
        parsing.Parser().parseOne(ims=bytearray(debBevVrcs), kvy=bevKevery)
        # bevKevery.processOne(ims=bytearray(debBevVrcs))  # give copy to process

        # now setup conjoint replay

        # Replay Deb's First Seen Events with receipts (vrcs and rcts) from both Cam and Bev
        # datetime is different in each run in the fse attachment in clone replay
        # so we either have to force dts in db or we parse in pieces
        debFelMsgs = bytearray()
        fn = 0
        cloner = debHab.db.clonePreIter(pre=debHab.pre,
                                        fn=fn)  # create iterator
        msg = next(cloner)  # get zeroth event with attachments
        assert len(msg) == 1423
        debFelMsgs.extend(msg)

        # parse msg
        serder = coring.Serder(raw=msg)
        assert serder.raw == debHab.iserder.raw
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.icp
        del msg[:len(serder.raw)]
        assert len(msg) == 1076

        counter = coring.Counter(
            qb64b=msg)  # attachment length quadlets counter
        assert counter.code == coring.CtrDex.AttachedMaterialQuadlets
        assert counter.count == (len(msg) - len(counter.qb64b)) // 4 == 268
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1072 == 268 * 4

        counter = coring.Counter(qb64b=msg)  # indexed signatures counter
        assert counter.code == coring.CtrDex.ControllerIdxSigs
        assert counter.count == 3  #  multisig deb
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1068

        for i in range(counter.count):  # parse signatures
            siger = coring.Siger(qb64b=msg)
            del msg[:len(siger.qb64b)]
        assert len(msg) == 1068 - 3 * len(siger.qb64b) == 804

        counter = coring.Counter(qb64b=msg)  # trans receipt (vrc) counter
        assert counter.code == coring.CtrDex.TransReceiptQuadruples
        assert counter.count == 3  #  multisig cam
        del msg[:len(counter.qb64b)]
        assert len(msg) == 800

        for i in range(counter.count):  # parse receipt quadruples
            prefixer, seqner, diger, siger = eventing.deTransReceiptQuadruple(
                msg, strip=True)
        assert len(msg) == 800 - 3 * (len(prefixer.qb64b) + len(
            seqner.qb64b) + len(diger.qb64b) + len(siger.qb64b)) == 200

        counter = coring.Counter(qb64b=msg)  # nontrans receipt (rct) counter
        assert counter.code == coring.CtrDex.NonTransReceiptCouples
        assert counter.count == 1  #  single sig bev
        del msg[:len(counter.qb64b)]
        assert len(msg) == 196

        for i in range(counter.count):  # parse receipt couples
            prefixer, cigar = eventing.deReceiptCouple(msg, strip=True)
        assert len(
            msg) == 196 - 1 * (len(prefixer.qb64b) + len(cigar.qb64b)) == 64

        counter = coring.Counter(qb64b=msg)  # first seen replay couple counter
        assert counter.code == coring.CtrDex.FirstSeenReplayCouples
        assert counter.count == 1
        del msg[:len(counter.qb64b)]
        assert len(msg) == 60

        seqner = coring.Seqner(qb64b=msg)
        assert seqner.sn == fn == 0
        del msg[:len(seqner.qb64b)]
        assert len(msg) == 36  # 24 less

        dater = coring.Dater(qb64b=msg)
        assert (helping.fromIso8601(helping.nowIso8601()) -
                helping.fromIso8601(dater.dts)) > datetime.timedelta()
        del msg[:len(dater.qb64b)]
        assert len(msg) == 0  # 36 less

        cloner.close()  # must close or get lmdb error upon with exit
        """Exception ignored in: <generator object LMDBer.getAllOrdItemPreIter at 0x106fe1c10>
        Traceback (most recent call last):
        File "/Users/Load/Data/Code/public/keripy/src/keri/db/dbing.py", line 512, in getAllOrdItemPreIter
        yield (cn, bytes(val))  # (on, dig) of event
        lmdb.Error: Attempt to operate on closed/deleted/dropped object.
        """

        fn += 1
        cloner = debHab.db.clonePreIter(pre=debHab.pre,
                                        fn=fn)  # create iterator not at 0
        msg = next(cloner)  # next event with attachments
        assert len(msg) == 1228
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.ixn
        debFelMsgs.extend(msg)

        fn += 1
        msg = next(cloner)  # get zeroth event with attachments
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.rot
        assert len(msg) == 1476
        assert ([verfer.qb64 for verfer in serder.verfers
                 ] == [verfer.qb64 for verfer in debHab.kever.verfers])
        debFelMsgs.extend(msg)

        fn += 1
        while (fn <= 6):
            msg = next(cloner)  # get zeroth event with attachments
            serder = coring.Serder(raw=msg)
            assert serder.sn == fn  # no recovery forks so sn == fn
            assert serder.ked["t"] == coring.Ilks.ixn
            assert len(msg) == 1228
            debFelMsgs.extend(msg)
            fn += 1

        assert len(debFelMsgs) == 9039
        cloner.close()  # must close or get lmdb error upon with exit

        msgs = debHab.replay()
        assert msgs == debFelMsgs

        # Play Cam's messages to Bev
        parsing.Parser().parse(ims=bytearray(camMsgs), kvy=bevKevery)
        # bevKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in bevKevery.kevers
        assert bevKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(bevKevery.cues) == 1

        # Play Bev's messages to Cam
        parsing.Parser().parse(ims=bytearray(bevMsgs), kvy=camKevery)
        # camKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in camKevery.kevers
        assert camKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(camKevery.cues) == 1

        camDebFelMsgs = camHab.replay(pre=debHab.pre)
        bevDebFelMsgs = bevHab.replay(pre=debHab.pre)

        assert len(bevDebFelMsgs) == len(camDebFelMsgs) == len(
            debFelMsgs) == 9039

        # create non-local kevery for Art to process conjoint replay msgs from Deb
        artKevery = eventing.Kevery(db=artHab.db, lax=False, local=False)
        # process Cam's inception so Art will proces Cam's vrcs without escrowing
        camIcpMsg = camHab.makeOwnInception()
        parsing.Parser().parse(ims=bytearray(camIcpMsg), kvy=artKevery)
        # artKevery.process(ims=bytearray(camIcpMsg))
        assert camHab.pre in artKevery.kevers
        assert len(artKevery.cues) == 1

        # process in cloned mode
        artKevery.cloned = True
        parsing.Parser().parse(ims=bytearray(debFelMsgs), kvy=artKevery)
        assert debHab.pre in artKevery.kevers
        assert artKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(artKevery.cues) == 8
        artDebFelMsgs = artHab.replay(pre=debHab.pre)
        assert len(artDebFelMsgs) == 9039

    assert not os.path.exists(artKS.path)
    assert not os.path.exists(artDB.path)
    assert not os.path.exists(bevKS.path)
    assert not os.path.exists(bevDB.path)
    assert not os.path.exists(camKS.path)
    assert not os.path.exists(camDB.path)
    assert not os.path.exists(debKS.path)
    assert not os.path.exists(debDB.path)
    """End Test"""
示例#9
0
def test_proving():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64
    hanSalt = coring.Salter(raw=b'abcdef0123456789').qb64
    vicSalt = coring.Salter(raw=b'fedcba9876543210').qb64

    with basing.openDB(name="sid") as sidDB, \
            keeping.openKS(name="sid") as sidKS, \
            basing.openDB(name="vic") as vicDB, \
            keeping.openKS(name="vic") as vicKS, \
            basing.openDB(name="han") as hanDB, \
            keeping.openKS(name="han") as hanKS, \
            openPocket(name="han") as hanPDB:
        limit = 1.0
        tock = 1.0
        doist = doing.Doist(limit=limit, tock=tock)

        sidHab = habbing.Habitat(ks=sidKS, db=sidDB, salt=sidSalt, temp=True)
        assert sidHab.pre == "E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E"
        sidIcpMsg = sidHab.makeOwnInception()

        hanKvy = eventing.Kevery(db=hanDB)
        parsing.Parser().parse(ims=bytearray(sidIcpMsg), kvy=hanKvy)
        assert hanKvy.kevers[sidHab.pre].sn == 0  # accepted event

        hanHab = habbing.Habitat(ks=hanKS, db=hanDB, salt=hanSalt, temp=True)
        assert hanHab.pre == "EKDWzykRd45o5UQyprm_9e8UcltXGo1tZCrdfGBTA8tc"
        hanIcpMsg = hanHab.makeOwnInception()

        vicKvy = eventing.Kevery(db=vicDB)
        parsing.Parser().parse(ims=bytearray(hanIcpMsg), kvy=vicKvy)
        assert vicKvy.kevers[hanHab.pre].sn == 0  # accepted event

        vicHab = habbing.Habitat(ks=vicKS, db=vicDB, salt=vicSalt, temp=True)
        assert vicHab.pre == "E8HQASAgOnZnQ4T7rv3dcvj0-UydrTTtyCprhEASk__o"
        vicIcpMsg = vicHab.makeOwnInception()

        parsing.Parser().parse(ims=bytearray(vicIcpMsg), kvy=hanKvy)
        assert hanKvy.kevers[vicHab.pre].sn == 0  # accepted event

        sed = dict()
        sed["$id"] = ""
        sed["$schema"] = "http://json-schema.org/draft-07/schema#"
        sed.update(
            dict(type="object",
                 properties=dict(id=dict(type="string"),
                                 lei=dict(type="string"))))

        schemer = scheming.Schemer(sed=sed,
                                   typ=scheming.JSONSchema(),
                                   code=coring.MtrDex.Blake3_256)
        cache = CacheResolver()
        cache.add(schemer.said, schemer.raw)
        jsonSchema = JSONSchema(resolver=cache)

        credSubject = dict(
            id=
            "did:keri:Efaavv0oadfghasdfn443fhbyyr4v",  # this needs to be generated from a KEL
            lei="254900OPPU84GM83MG36",
            issuanceDate="2021-06-27T21:26:21.233257+00:00",
        )

        creder = credential(issuer=sidHab.pre,
                            schema=schemer.said,
                            subject=credSubject,
                            typ=JSONSchema(resolver=cache))

        assert creder.said == "EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM"

        msg = sidHab.endorse(serder=creder)
        hanWallet = Wallet(hab=hanHab, db=hanPDB)

        parseCredential(ims=msg,
                        wallet=hanWallet,
                        typ=JSONSchema(resolver=cache))

        # verify we can load serialized VC by SAID
        key = creder.said.encode("utf-8")
        assert hanPDB.getSers(key) is not None

        # Create Red's wallet and Issue Handler for receiving the credential
        hanRequestHandler = RequestHandler(wallet=hanWallet, typ=jsonSchema)
        hanExc = exchanging.Exchanger(hab=hanHab,
                                      tymth=doist.tymen(),
                                      handlers=[hanRequestHandler])

        # Create the issue credential payload
        pl = dict(input_descriptors=[dict(x=schemer.said)])

        # Create the `exn` message for presentation request
        vicExcSrdr = exchanging.exchange(route="/presentation/request",
                                         payload=pl)
        excMsg = vicHab.sanction(vicExcSrdr)

        # Parse the exn presentation request message on Han's side
        parsing.Parser().parse(ims=bytearray(excMsg), kvy=hanKvy, exc=hanExc)
        doist.do(doers=[hanExc])
        assert doist.tyme == limit

        resp = hanRequestHandler.cues.popleft()
        assert resp is not None

        respSer = coring.Serder(raw=resp.raw)
        assert respSer.ked['t'] == coring.Ilks.exn
        assert respSer.ked['r'] == "/presentation/proof"
        data = respSer.ked['q']
        assert "presentation_submission" in data

        pe = data["presentation_submission"]
        assert "descriptor_map" in pe

        dm = pe["descriptor_map"]
        assert len(dm) == 1
        assert dm[0]["id"] == schemer.said

        assert "verifiableCredential" in data
        vcs = data["verifiableCredential"]
        assert len(vcs) == 1

        proof = (
            "-FABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw"
            "-AxDNI7_ZmaI-AABAA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA"
        )
        assert vcs[0]["proof"] == proof
示例#10
0
def test_proving():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64

    with basing.openDB(name="sid") as sidDB, \
            keeping.openKS(name="sid") as sidKS:
        sidHab = habbing.Habitat(ks=sidKS, db=sidDB, salt=sidSalt, temp=True)
        assert sidHab.pre == "E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E"
        sed = dict()
        sed["$id"] = ""
        sed["$schema"] = "http://json-schema.org/draft-07/schema#"
        sed.update(
            dict(type="object",
                 properties=dict(id=dict(type="string"),
                                 lei=dict(type="string"))))

        schemer = scheming.Schemer(sed=sed,
                                   typ=scheming.JSONSchema(),
                                   code=coring.MtrDex.Blake3_256)
        credSubject = dict(
            id=
            "did:keri:Efaavv0oadfghasdfn443fhbyyr4v",  # this needs to be generated from a KEL
            lei="254900OPPU84GM83MG36",
            issuanceDate="2021-06-27T21:26:21.233257+00:00",
        )

        cache = CacheResolver()
        cache.add(schemer.said, schemer.raw)

        creder = credential(issuer=sidHab.pre,
                            schema=schemer.said,
                            subject=credSubject,
                            typ=JSONSchema(resolver=cache))

        msg = sidHab.endorse(serder=creder)
        assert msg == (
            b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",'
            b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",'
            b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",'
            b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}-VA0-FABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE'
            b'-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw-AxDNI7_ZmaI'
            b'-AABAA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA'
        )

        creder = Credentialer(raw=msg, typ=JSONSchema(resolver=cache))
        proof = msg[creder.size:]

        ctr = Counter(qb64b=proof, strip=True)
        assert ctr.code == CtrDex.AttachedMaterialQuadlets
        assert ctr.count == 52

        pags = ctr.count * 4
        assert len(proof) == pags

        ctr = Counter(qb64b=proof, strip=True)
        assert ctr.code == CtrDex.TransIndexedSigGroups
        assert ctr.count == 1

        prefixer = Prefixer(qb64b=proof, strip=True)
        assert prefixer.qb64 == sidHab.pre

        seqner = Seqner(qb64b=proof, strip=True)
        assert seqner.sn == sidHab.kever.sn

        diger = Diger(qb64b=proof, strip=True)
        assert diger.qb64 == sidHab.kever.serder.dig

        ictr = Counter(qb64b=proof, strip=True)
        assert ictr.code == CtrDex.ControllerIdxSigs

        isigers = []
        for i in range(ictr.count):
            isiger = Siger(qb64b=proof, strip=True)
            isiger.verfer = sidHab.kever.serder.verfers[i]
            isigers.append(isiger)
        assert len(isigers) == 1

        siger = isigers[0]
        assert siger.verfer.verify(siger.raw, creder.raw) is True
示例#11
0
def test_wallet():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64

    with basing.openDB(name="sid") as sidDB, \
            keeping.openKS(name="sid") as sidKS, \
            openPocket(name="sid") as sidPDB:
        sidHab = habbing.Habitat(ks=sidKS, db=sidDB, salt=sidSalt, temp=True)
        assert sidHab.pre == "E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E"

        sed = dict()
        sed["$id"] = ""
        sed["$schema"] = "http://json-schema.org/draft-07/schema#"
        sed.update(dict(
            type="object",
            properties=dict(
                id=dict(
                    type="string"
                ),
                lei=dict(
                    type="string"
                )
            )
        ))

        schemer = scheming.Schemer(sed=sed, typ=scheming.JSONSchema(), code=coring.MtrDex.Blake3_256)
        credSubject = dict(
            id="did:keri:Efaavv0oadfghasdfn443fhbyyr4v",  # this needs to be generated from a KEL
            lei="254900OPPU84GM83MG36",
            issuanceDate="2021-06-27T21:26:21.233257+00:00",
        )

        cache = CacheResolver()
        cache.add(schemer.said, schemer.raw)

        creder = credential(issuer=sidHab.pre,
                            schema=schemer.said,
                            subject=credSubject,
                            typ=JSONSchema(resolver=cache))
        assert creder.said == "EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM"

        msg = sidHab.endorse(serder=creder)
        assert msg == (
            b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",'
            b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",'
            b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",'
            b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}-VA0-FABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE'
            b'-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw-AxDNI7_ZmaI'
            b'-AABAA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA')
        ser = (
            b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",'
            b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",'
            b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",'
            b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}')
        seal = (
            b'E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw'
            b'-AxDNI7_ZmaI')

        sig0 = (
            b'AA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA'
        )

        sidWallet = Wallet(hab=sidHab, db=sidPDB)

        parseCredential(ims=msg, wallet=sidWallet, typ=JSONSchema(resolver=cache))

        # verify we can load serialized VC by SAID
        key = creder.said.encode("utf-8")
        assert sidPDB.getSers(key) == ser

        # verify the signature
        sigs = sidPDB.getSigs(key)
        assert len(sigs) == 1
        assert sigs[0] == sig0

        # verify the seal
        sl = sidPDB.getSeals(key)
        assert sl == seal

        # verify we can look up credential by Schema SAID
        schema = sidPDB.getSchms(schemer.saider.qb64b)
        assert len(schema) == 1
        assert schema[0] == key
示例#12
0
def test_weighted():
    """
    Test multisig with weighted threshold

    """
    wesSalt = coring.Salter(raw=b'0123456789abcdef').qb64  # init wes Salter

    # init event DB and keep DB
    with dbing.openDB(name="wes") as wesDB, keeping.openKS(
            name="wes") as wesKS:
        # Init key pair manager
        wesMgr = keeping.Manager(keeper=wesKS, salt=wesSalt)

        # Init Kevery with event DB
        wesKvy = eventing.Kevery(db=wesDB)

        # create inception event for Wes with 3 keys each in incept and next sets
        # defaults are algo salty and rooted
        sith = ["1/2", "1/2", "1/2"]  #  2 of 3 but with weighted threshold
        nxtsith = ["1/2", "1/2", "1/2"]
        verfers, digers, cst, nst = wesMgr.incept(icount=3,
                                                  isith=sith,
                                                  ncount=3,
                                                  nsith=nxtsith,
                                                  stem='wes',
                                                  temp=True)
        assert cst == nst == sith

        wesSrdr = eventing.incept(
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            code=coring.MtrDex.Blake3_256)

        wesPre = wesSrdr.ked["i"]

        wesMgr.move(old=verfers[0].qb64,
                    new=wesPre)  # move key pair label to prefix

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON00015b_","i":"EX0WJtv6vc0IWzOqa92Pv9v9pgs1f0BfIV'
            b'rSch648Zf0","s":"0","t":"icp","kt":["1/2","1/2","1/2"],"k":["DK4'
            b'OJI8JOr6oEEUMeSF_X-SbKysfwpKwW-ho5KARvH5c","D1RZLgYke0GmfZm-CH8A'
            b'sW4HoTU4m-2mFgu8kbwp8jQU","DBVwzum-jPfuUXUcHEWdplB4YcoL3BWGXK0TM'
            b'oF_NeFU"],"n":"EhJGhyJQTpSlZ9oWfQT-lHNl1woMazLC42O89fRHocTI","bt'
            b'":"0","b":[],"c":[],"a":[]}-AADAAKWMK8k4Po2A0rBrUBjBom73DfTCNg_b'
            b'iwR-_LWm6DMHZHGDfCuOmEyR8sEdp7cPxhsavq4istIZ_QQ42yyUcDAABeTClYkN'
            b'-yjbW3Kz3ot6MvAt5Se-jmcjhu-Cfsv4m_GKYgc_qwel1SbAcqF0TiY0EHFdjNKv'
            b'Ikg3q19KlhSbuBgACA6QMnsnZuy66xrZVg3c84mTodZCEvOFrAIDQtm8jeXeCTg7'
            b'yFauoQECZyNIlUnnxVHuk2_Fqi5xK_Lu9Pt76Aw')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        wesK = wesKvy.kevers[wesPre]  # kever created so event was validated
        assert wesK.prefixer.qb64 == wesPre
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # create interaction event for Wes
        wesSrdr = eventing.interact(pre=wesK.prefixer.qb64,
                                    dig=wesK.serder.diger.qb64,
                                    sn=wesK.sn + 1,
                                    data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=wesK.verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000098_","i":"EX0WJtv6vc0IWzOqa92Pv9v9pgs1f0BfIV'
            b'rSch648Zf0","s":"1","t":"ixn","p":"EInuqF20s1O0JhVJaOuKCZZDDyw6D'
            b'YxATbiuC5Hv3WXs","a":[]}-AADAAmg8UoBCTlnENiySBpn6j7mR1w0gdkfC8Ai'
            b'aYL5NCFfePp5ZK3CmnP7oQdj_ggiNp9FZNE0Q69A99wNK5FrwzDgABQZZunmJr2X'
            b'3BYgX34-6SOpzkHZQS99ZL0tDsDyUIL7jZhD1e1203Fh6BnkDjzum2au2dGHJcIP'
            b'giFGfDsrI5DwACwwYqqYYdEXeLpx_o6LTSKU-Fz_WF2gebP9Z72bZ75atg7_ZM3H'
            b'g6hhztstGt8TthRQ0TJn6rkvatkbn6yzRjBw')

        # apply msg to wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        nxtsith = ["1/2", "1/2", "1/2"]  #  2 of 3 but with weighted threshold
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=3,
                                                  sith=nxtsith,
                                                  temp=True)
        assert nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert bytearray(
            b'{"v":"KERI10JSON000190_","i":"EX0WJtv6vc0IWzOqa92Pv9v9pgs1f0BfIV'
            b'rSch648Zf0","s":"2","t":"rot","p":"EznUtmH2XJF04dyqpUHLzwkNgwk6D'
            b'jbDFbjXVI3UJLe0","kt":["1/2","1/2","1/2"],"k":["DeonYM2bKnAwp6VZ'
            b'cuCXdX72kNFw56czlZ_Tc7XHHVGI","DQghKIy-2do9OkweSgazh3Ql1vCOt5bnc'
            b'5QF8x50tRoU","DNAUn-5dxm6b8Njo01O0jlStMRCjo9FYQA2mfqFW1_JA"],"n"'
            b':"EX5fxvjOg5VuDboWbqnTjTPpXa3nNIm99hlsB1EmhTo8","bt":"0","br":[]'
            b',"ba":[],"a":[]}-AADAAahiASmZJY2KjXKRvVwdRSESmesNsfxUnOQ6buEk6S-'
            b'4rxRdztde_6_CX2Q4MyUSErHMtmLhesrKjenPBairZAQABbnbZ3lOKcKCMmLYtpT'
            b'hDEm-tRTsnEh_8loXpA6G3q1oJZNeVJphJjPm2HR0mX2ptC2DEt6p9i4GH1Y56HY'
            b'TsAgACqF6e_29QkxgXvqDLEUnAIB_XJ7SUhDNpt3cYk6pF1-ULgrhGdZLS1h-c_V'
            b'KpKITRx3ZTvme7sKbvr_NfR-0ECg')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        sith = nxtsith  # rotate so nxtsith is now current sith and need new nextsith
        #  2 of first 3 and 1 of last 2
        nxtsith = [["1/2", "1/2", "1/2"], ["1/1", "1/1"]]
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=5,
                                                  sith=nxtsith,
                                                  temp=True)
        assert cst == sith
        assert nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000190_","i":"EX0WJtv6vc0IWzOqa92Pv9v9pgs1f0BfIV'
            b'rSch648Zf0","s":"3","t":"rot","p":"EK1BTah7lTyaaol7sLdg9uObplAjP'
            b'o_JOz1m4WPaLJBw","kt":["1/2","1/2","1/2"],"k":["D7WWKDLVwYxYMLAj'
            b'DceIEs66xPMY4Afzx-RQw2x0mQzI","Dmg6Aah8qyKKDiQyNXTiO71QJwizjZfGM'
            b'61BA-s0A5F4","DS3fhKpvPCDL5WmfN4_PkmJMMsSCdRTxG24OQuf_EmHQ"],"n"'
            b':"EcM4iw7fElXWhad8V-za4Px7nBKjndxoh3XZRkohghKY","bt":"0","br":[]'
            b',"ba":[],"a":[]}-AADAAl6FtC6Ynm8RAoa2utkIqJX5xW1ZxIkEH7I_MUCXL0p'
            b'OUT8P0lCgPzn9dvmUagHbzZ4GIwOBqGI-lQJbeESnZBQAB_nJLQJTf9t1NJxNoP5'
            b'gve9QEQbHFkn2aX6O78_bzOGUf01y8KSl-ugi0_B9-w0dk4J7gjYbv7RhG-TmFPE'
            b'mEAAACEpJiOTGarwK4jWZ9ZKue05uYPDW5wp4HC8VIt6R93h7WHLqqLVH1m3n5jd'
            b'AkiM4RFdhUqBwt-jKBfHQmVoBBCA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

        # Create rotation event for Wes
        # get current keys as verfers and next digests as digers
        sith = nxtsith  # rotate so nxtsith is now current sith and need new nextsith
        #  2 of first 3 and 1 of last 2
        nxtsith = [["1/2", "1/2", "1/2"], ["1/1", "1/1"]]
        verfers, digers, cst, nst = wesMgr.rotate(pre=wesPre,
                                                  count=5,
                                                  sith=nxtsith,
                                                  temp=True)
        assert cst == nst == nxtsith

        wesSrdr = eventing.rotate(
            pre=wesK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            sith=sith,
            dig=wesK.serder.diger.qb64,
            nxt=coring.Nexter(sith=nxtsith,
                              digs=[diger.qb64 for diger in digers]).qb64,
            sn=wesK.sn + 1,
            data=[])

        sigers = wesMgr.sign(ser=wesSrdr.raw, verfers=verfers)

        msg = bytearray(wesSrdr.raw)
        counter = coring.Counter(coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON0001fe_","i":"EX0WJtv6vc0IWzOqa92Pv9v9pgs1f0BfIV'
            b'rSch648Zf0","s":"4","t":"rot","p":"EVfMO5GK8tg4KE8XCelX1s_TG_Hqr'
            b'_kzb3ghIBYvzC6U","kt":[["1/2","1/2","1/2"],["1/1","1/1"]],"k":["'
            b'DToUWoemnetqJoLFIqDI7lxIJEfF0W7xG5ZlqAseVUQc","Drz-IZjko61q-sPMD'
            b'IW6n-0NGFubbXiZhzWZrO_BZ0Wc","DiGwL3hjQqiUgQlFPeA6kRR1EBXX0vSLm9'
            b'b6QhPS8IkQ","Dxj5pcStgZ6CbQ2YktNaj8KLE_g9YAOZF6AL9fyLcWQw","DE5z'
            b'r5eH8EUVQXyAaxWfQUWkGCId-QDCvvxMT77ibj2Q"],"n":"E3in3Z14va0kk4Wq'
            b'd3vcCAojKNtQq7ZTrQaavR8x0yu4","bt":"0","br":[],"ba":[],"a":[]}-A'
            b'AFAAdxx4UfoNYdXckLY9nSYvqYLJzvIRhixshBbqkQ6uwvqaVmwPqmvck0V9xl5x'
            b'3ssVclasm8Ga3FTkcbmbV2jXDgABBWUhku-qDq8wYn5XMQuKzidAsA6bth8-EsCx'
            b'9WwTIqWBR-AecW-3X1haAyJshqplDsS9MnZfVgmSHokwdLnRCQACp2tB0pFRv_C7'
            b'nUXPf9rFKvlWUllrsY6Y1_F4bAOMvyCU-PES4HwyUQv3kQnLxEqnf0fbOYdHJNGo'
            b'sXi-UqL9BAADW89YpsS5m3IASAtXvXEPez-0y11JRP8bAiUUBdIxGB9ms79jPZnQ'
            b'tF3045byf3m0Dvi91Y9d4sh-xkzZ15v9DAAE6QR9qNXnHXLisg4Mbadav9AdMjS4'
            b'uz6jNG1AL6UCa7P90Y53v1V6VRaOPu_RTWXcXYRGqA9BHJ2rLNYWJTJTBA')

        # apply msg to Wes's Kevery
        wesKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert wesK.serder.diger.qb64 == wesSrdr.dig  # key state updated so event was validated

    assert not os.path.exists(wesKS.path)
    assert not os.path.exists(wesDB.path)
    """End Test"""
示例#13
0
def test_mailboxing():
    """
    Test Mailboxer Class
    """
    mber = Mailboxer()

    assert isinstance(mber, Mailboxer)
    assert mber.name == "main"
    assert mber.temp is False
    assert isinstance(mber.env, lmdb.Environment)
    assert mber.path.endswith("keri/mbx/main")
    assert mber.env.path() == mber.path
    assert os.path.exists(mber.path)

    assert isinstance(mber.fels, lmdb._Database)

    mber.close(clear=True)
    assert not os.path.exists(mber.path)
    assert not mber.opened

    mber = Mailboxer(reopen=False)
    assert isinstance(mber, Mailboxer)
    assert mber.name == "main"
    assert mber.temp is False
    assert mber.opened is False
    assert mber.path is None
    assert mber.env is None

    mber.reopen()
    assert mber.opened
    assert mber.path is not None
    assert isinstance(mber.env, lmdb.Environment)
    assert mber.path.endswith("keri/mbx/main")
    assert mber.env.path() == mber.path
    assert os.path.exists(mber.path)

    mber.close(clear=True)
    assert not os.path.exists(mber.path)
    assert not mber.opened

    assert isinstance(mber.exns, subing.SerderSuber)

    with dbing.openLMDB(cls=Mailboxer) as mber:
        assert isinstance(mber, Mailboxer)

        msg = bytearray(
            b'{"v":"KERI10JSON0000ac_","t":"exn","i":"E4D919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I",'
            b'"dt":"2021-07-15T13:01:37.624492+00:00","r":"/credential/issue","q":{"a":"b",'
            b'"b":123}}-HABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E'
            b'-AABAAMKEkKlqSYcAbOHfNXQ_D0Rbj9bQD5FqhFqckAlDnOFozRKOIPrCWaszRzSUN20UBj80tO5ozN35KrQp9m7Z1AA'
        )

        dest = coring.Prefixer(
            qb64="E4D919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I")
        source = coring.Prefixer(
            qb64="E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E")
        siger = coring.Siger(
            qb64=
            "AAMKEkKlqSYcAbOHfNXQ_D0Rbj9bQD5FqhFqckAlDnOFozRKOIPrCWaszRzSUN20UBj80tO5ozN35KrQp9m7Z1AA"
        )

        d = dict(a="b", b=123)
        exn = exchanging.exchange("/credential/issue",
                                  payload=d,
                                  recipient=dest.qb64,
                                  date="2021-07-15T13:01:37.624492+00:00")
        mber.storeEvent(serder=exn, source=source, dest=dest, sigers=[siger])

        actual = mber.cloneEvtMsg(dig=exn.digb)
        assert actual == msg

    assert not os.path.exists(mber.path)

    with dbing.openLMDB(cls=Mailboxer) as mber, \
            basing.openDB(name="test") as db, \
            keeping.openKS(name="test") as ks:

        salt = coring.Salter(raw=b'0123456789abcdef').qb64
        hab = habbing.Habitat(ks=ks, db=db, salt=salt, temp=True)

        for idx in range(10):
            d = dict(a="b", b=idx)
            dest = coring.Prefixer(
                qb64="E4D919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I")
            source = coring.Prefixer(
                qb64="E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E")

            exn = exchanging.exchange("/credential/issue",
                                      payload=d,
                                      recipient=dest.qb64,
                                      date="2021-07-15T13:01:37.624492+00:00")
            sigers = hab.mgr.sign(ser=exn.raw, verfers=hab.kever.verfers)
            mber.storeEvent(serder=exn,
                            source=source,
                            dest=dest,
                            sigers=sigers)

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=0):
            msgs.append(msg)

        assert (len(msgs)) == 10

        for idx, msg in enumerate(msgs):
            exn = coring.Serder(msg)
            d = exn.ked["q"]
            assert d["b"] == idx

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=10):
            msgs.append(msg)

        assert (len(msgs)) == 0

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=4):
            msgs.append(msg)

        assert (len(msgs)) == 6
示例#14
0
def test_store_exchanger():
    with dbing.openLMDB(cls=Mailboxer) as mber, \
            basing.openDB(name="test") as db, \
            keeping.openKS(name="test") as ks:

        salt = coring.Salter(raw=b'0123456789abcdef').qb64
        hab = habbing.Habitat(ks=ks, db=db, salt=salt, temp=True)
        exchr = exchanging.StoreExchanger(hab=hab, mbx=mber)

        source = coring.Prefixer(
            qb64="E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E")
        siger = coring.Siger(
            qb64=
            "AAMKEkKlqSYcAbOHfNXQ_D0Rbj9bQD5FqhFqckAlDnOFozRKOIPrCWaszRzSUN20UBj80tO5ozN35KrQp9m7Z1AA"
        )

        d = dict(a="b", b=123)
        exn = exchanging.exchange("/credential/issue",
                                  payload=d,
                                  date="2021-07-15T13:01:37.624492+00:00")
        with pytest.raises(MissingSignatureError):
            exchr.processEvent(serder=exn, source=source, sigers=[siger])

        sigers = hab.mgr.sign(ser=exn.raw, verfers=hab.kever.verfers)
        with pytest.raises(MissingDestinationError):
            exchr.processEvent(serder=exn, source=source, sigers=sigers)

        for idx in range(10):
            d = dict(a="b", b=idx)
            dest = coring.Prefixer(
                qb64="E4D919wF4oiG7ck6mnBWTRD_Z-Io0wZKCxL0zjx5je9I")
            source = coring.Prefixer(
                qb64="E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E")

            exn = exchanging.exchange("/credential/issue",
                                      payload=d,
                                      recipient=dest.qb64,
                                      date="2021-07-15T13:01:37.624492+00:00")
            sigers = hab.mgr.sign(ser=exn.raw, verfers=hab.kever.verfers)
            exchr.processEvent(serder=exn, source=source, sigers=sigers)

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=0):
            msgs.append(msg)

        assert (len(msgs)) == 10

        for idx, msg in enumerate(msgs):
            exn = coring.Serder(msg)
            d = exn.ked["q"]
            assert d["b"] == idx

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=10):
            msgs.append(msg)

        assert (len(msgs)) == 0

        msgs = []
        for msg in mber.clonePreIter(pre=dest.qb64b, fn=4):
            msgs.append(msg)

        assert (len(msgs)) == 6
示例#15
0
def test_replay():
    """
    Test disjoint and conjoint replay

    Deb creates series of events.
    Deb replays Deb's events to Cam and collects Cam's receipts
    Deb replays Deb's events with Cam's recepts to Bev and collects Bev's receipts
    Deb replays Deb's events with both Cam's and  Bev's receipts to Cam
    Compare replay of Deb's events with receipts by both Deb and Cam to confirm identical
    """

    with dbing.openDB(name="deb") as debDB, keeping.openKS(name="deb") as debKS, \
         dbing.openDB(name="cam") as camDB, keeping.openKS(name="cam") as camKS, \
         dbing.openDB(name="bev") as bevDB, keeping.openKS(name="bev") as bevKS, \
         dbing.openDB(name="art") as artDB, keeping.openKS(name="art") as artKS:

        # setup Deb's habitat using default salt multisig already incepts
        sith = ["1/2", "1/2", "1/2"]  # weighted signing threshold
        debHab = directing.Habitat(ks=debKS, db=debDB, isith=sith, icount=3,
                                   temp=True)
        assert debHab.ks == debKS
        assert debHab.db == debDB
        assert debHab.kever.prefixer.transferable

        # setup Cam's habitat using default salt multisig already incepts
        # Cam's receipts will be vrcs with 3 indexed sigantures attached
        sith = '2'  # hex str of threshold int
        camHab = directing.Habitat(ks=camKS, db=camDB, isith=sith, icount=3,
                                   temp=True)
        assert camHab.ks == camKS
        assert camHab.db == camDB
        assert camHab.kever.prefixer.transferable

        # setup Bev's habitat using default salt nonstransferable already incepts
        # Bev's receipts will be rcts with a receipt couple attached
        sith = '1'  # hex str of threshold int
        bevHab = directing.Habitat(ks=bevKS, db=bevDB, isith=sith, icount=1,
                                   transferable=False, temp=True)
        assert bevHab.ks == bevKS
        assert bevHab.db == bevDB
        assert not bevHab.kever.prefixer.transferable

        # setup Art's habitat using custom salt nonstransferable so not match Bev
        # already incepts
        # Art's receipts will be rcts with a receipt couple attached
        salt = coring.Salter(raw=b'abcdef0123456789').qb64
        sith = '1'  # hex str of threshold int
        artHab = directing.Habitat(ks=artKS, db=artDB, isith=sith, icount=1,
                                   salt=salt, transferable=False, temp=True)
        assert artHab.ks == artKS
        assert artHab.db == artDB
        assert not artHab.kever.prefixer.transferable

        # first setup disjoint replay then conjoint replay
        # Create series of event for Deb
        debMsgs = bytearray()
        debMsgs.extend(debHab.makeOwnInception())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.rotate())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())

        assert debMsgs == bytearray(b'{"v":"KERI10JSON000154_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wa'
                                    b'pj3LcQ8CT4","s":"0","t":"icp","kt":["1/2","1/2","1/2"],"k":["DaY'
                                    b'h8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg","Duzj-Z2lR2DqB0cI0421'
                                    b'oSMUVWOrN5axojx8g9fSx3PM","DRXPAmNVVqafWvQiN5qQmWUDvVupF2w8xFNGg'
                                    b'1Gays9Y"],"n":"EO5f_IQjtBoeN_-OyzfVJx1_WqBFUL-Ely4x-xmUtOW8","wt'
                                    b'":"0","w":[],"c":[]}-AADAA6Z50BRlXby_uSdkqbybLXds-5OMwQil4miux1s'
                                    b'RxJkiD3kRS4HuCpv5m-wwsPHWwn_Ku5xB2P--NJ1pl7KXjAQABDjMdRtemkn9oyk'
                                    b'LFo9MBwZsS85hGd1yaMMdFb_P1FY8_PZcHBVTc2iF5Bd6T2rGorwS-ChRa24bxUr'
                                    b'kemWD1DAACpxUYq2zrFAlMdWuxdaYTqvh12pgk4Ba-vllsaZP5ct5HcOtJw47B6c'
                                    b'VLcEePwEHk6jHlSoDGgH2YiyOwPbgSBQ{"v":"KERI10JSON000098_","i":"E4'
                                    b'ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"1","t":"ixn","p'
                                    b'":"Egd_fi2QDtfjjdB5p9tT6QCHuBsSWUwQP6AbarcjLgw0","a":[]}-AADAAPL'
                                    b'MNHELcDDuPT1gyI9_TEBM6FRji2xmc0iBfNBwoKJttbJfeQhH41y-ayubtyhyMzH'
                                    b'aqrq-WXaNQkpnzTTOPBAABUawpt1Nd7GR9rTwPD4ucT-M7Vy1xuxGlgRf9pgkOcX'
                                    b'BBbhomjjEpz3aid9PP2vWeJ_rvw7W5rgrTJ38Q2v8bDwACoHNjlZ-IZ1K9opgeu3'
                                    b'3TNIFBd3rNW_gKO_bFa-t2GYwOzlWoDlzF7kSRQnVKlXMeVrLBe3uwO6PjYjeZdU'
                                    b'SlDg{"v":"KERI10JSON000190_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOv'
                                    b'W5Wapj3LcQ8CT4","s":"2","t":"rot","p":"E8MU3qwR6gzbMUqEXh0CgG4k3'
                                    b'k4WKkk9hM0iaVeCmG7E","kt":["1/2","1/2","1/2"],"k":["DIsi8qYso1KM'
                                    b'mpLOGYty3NC2BAojZmUCfzR5_5oQRiso","DkdClpaWCAoCPBYgUmqP9gwAtsGq8'
                                    b'1yyPhGQKQ6-W_F0","DKDyq4QQYKnx9ircxeCvEcraI4HUSr_ytWPelDHAM98w"]'
                                    b',"n":"E1oOvJmwenmC4uHjX7qB40LGVbeZY5rYQeZ6IK5zmdmM","wt":"0","wr'
                                    b'":[],"wa":[],"a":[]}-AADAAr5HeTAGJ_WfIMO82lbEnpAMkuqZ0iJO0yYhjwv'
                                    b'LElPYltF_jSOApKPWxepare2O7XMMOvtgxjXj9pvvqpW8WDgABKHoueBd4JgakpV'
                                    b'ydJYADwh5wMSNyHNMKXwhYMGrgApl_EvsTmEt8uS94PmrfCtRjLRbZdzLRZVkX7Y'
                                    b'x4jlNNCgACjKJlODGhL_a0S3-oDRJhOUG0sul4SCJd21Qp-KSFSfGavACAwQdEYQ'
                                    b'L43jko9lFDuhwKDt1BD8kAoy3T-tdoAw{"v":"KERI10JSON000098_","i":"E4'
                                    b'ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"3","t":"ixn","p'
                                    b'":"EO2hh7xg29y3i7uywQ_n0g7vk0W1oGiErUY9QpGjSUhc","a":[]}-AADAA5I'
                                    b'ox67c4HL78UrYqpSNH-UkHZRpR7X0fPQ0GEYJG8OGqCHBvPJica_yohOQP8GNOFQ'
                                    b'9UsmBa0TDji6EAaXivBwAB6BgG2CQ-Ukw8CchtCHf9L5kVsmg1Tu2OuLkcy9Sb9u'
                                    b'Vm23yLx-8I4pc6KHmZke8KCvpXjcdV65gOOE-VUIMOBwACXtTZoFqJHFhoMZABun'
                                    b'XETksrK1nNiP9xzXx13gl4uqoVZkqfwqUTL3C7q0RcxYwaz5sYSNQA8zblA8YxVy'
                                    b'FuCQ{"v":"KERI10JSON000098_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOv'
                                    b'W5Wapj3LcQ8CT4","s":"4","t":"ixn","p":"EQI0EXdK6WvQae17PBWDUkMOd'
                                    b'OiTPpx48oMSYTUYsCl0","a":[]}-AADAAbnPY1i0cpo6q0cmvQr2bZOcipzl7LY'
                                    b'Y2h-3ixndlzB3f-4VFLzSnIUtB_qwp1H2NI_DNGqXWGACywJoxkFccAQABHDicUl'
                                    b'iz3Bl6y1T7-sQteMKxoDYZ4A8hVx3p3EjztyO8UnA6PkaV2b7AFwAfk4UbBWKMGj'
                                    b'TtpZ88S7P9EsXLBAACNFFh6nDIWNG1ZbEsqqlCG2aKLgnpHmR6cJr1dq1F4pylAF'
                                    b'1e3-on2aasDMYk3c2fj-AWErRqbsf8ejnJE3YvDg{"v":"KERI10JSON000098_"'
                                    b',"i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"5","t":'
                                    b'"ixn","p":"EvrAC5XVQyu01ZuKfq1wiR0kXF2j8TjrCg4QyA0LVjKk","a":[]}'
                                    b'-AADAA1OJn3UHjLcI333fduqTj6nAJY27VtkQqW_lHalnJKtgmb0tk1tV5xUCVzp'
                                    b'al14xWDuyCdImhFzTk0sRgW4MYDQABOR8ay9qQYR3ieant4ujM_FX0Nm_mUHcVVo'
                                    b'4pCqDy8jLaM3EBNmkOKUIfxgZC-8k6OpYcy33gC-qgUpc6C2_PDwACSoZSibaYci'
                                    b'n32vY4ANzflFpJh_EF7mcGbTWSFrNLnwFrrOfhXL3i1Pf39Sk079ApSI87Nt-CvH'
                                    b'pRRdows3TABQ{"v":"KERI10JSON000098_","i":"E4ReNhXtuh4DAKe4_qcX__'
                                    b'uF70MnOvW5Wapj3LcQ8CT4","s":"6","t":"ixn","p":"EwmQtlcszNoEIDfqD'
                                    b'-Zih3N6o5B3humRKvBBln2juTEM","a":[]}-AADAAvYMCRmJgjFM7EG7rWng7Q3'
                                    b'WRfwcd908UdKL-7ZfGw4igpF9DcA-yxwliba59D4pkmhIcrW_Ax76iuaD6yD03Bw'
                                    b'AB9Wp-awBUfw2jnDRjvEU3xpFlLDHwiFLRKpom8Wnx7qDD4aEv6ERZh-H8yP3eL4'
                                    b'sNEFjP5HcRrb5MpFwOp0VyAwACdedbq9E2Exs1NobGwSNQpNxKlgDPiNDE8nOeOq'
                                    b'gXt1rAj8SAh8gX2pOgEFj3g3UB69dNGw2M-bEZ557-p9G-Aw')


        # Play debMsgs to Cam
        # create non-local kevery for Cam to process msgs from Deb
        camKevery = eventing.Kevery(kevers=camHab.kevers,
                                    db=camHab.db,
                                    framed=True,
                                    opre=camHab.pre,
                                    local=False)
        camKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in camKevery.kevers
        assert camKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(camKevery.cues) == 7

        # get disjoints receipts (vrcs) from Cam of Deb's events by processing Cam's cues
        camMsgs = camHab.processCues(camKevery.cues)
        assert camMsgs == bytearray(b'{"v":"KERI10JSON000144_","i":"E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-O'
                                    b'CPLbIhBO7Y","s":"0","t":"icp","kt":"2","k":["DaYh8uaASuDjMUd8_Bo'
                                    b'NyQs3GwupzmJL8_RBsuNtZHQg","Duzj-Z2lR2DqB0cI0421oSMUVWOrN5axojx8'
                                    b'g9fSx3PM","DRXPAmNVVqafWvQiN5qQmWUDvVupF2w8xFNGg1Gays9Y"],"n":"E'
                                    b'OySO3Oa400n3Ss9JftGYmgS5M4jgPInNnMntC_l-PEQ","wt":"0","w":[],"c"'
                                    b':[]}-AADAA5267UlFg1jHee4Dauht77SzGl8WUC_0oimYG5If3SdIOSzWM8Qs9SF'
                                    b'ajAilQcozXJVnbkY5stG_K4NbKdNB4AQABBgeqntZW3Gu4HL0h3odYz6LaZ_SMfm'
                                    b'ITL-Btoq_7OZFe3L16jmOe49Ur108wH7mnBaq2E_0U0N0c5vgrJtDpAQACTD7NDX'
                                    b'93ZGTkZBBuSeSGsAQ7u0hngpNTZTK_Um7rUZGnLRNJvo5oOnnC1J2iBQHuxoq8Py'
                                    b'jdT3BHS2LiPrs2Cg{"v":"KERI10JSON000105_","i":"E4ReNhXtuh4DAKe4_q'
                                    b'cX__uF70MnOvW5Wapj3LcQ8CT4","s":"0","t":"vrc","d":"Egd_fi2QDtfjj'
                                    b'dB5p9tT6QCHuBsSWUwQP6AbarcjLgw0","a":{"i":"E_T2_p83_gRSuAYvGhqV3'
                                    b'S0JzYEF2dIa-OCPLbIhBO7Y","s":"0","d":"EFSbLZkTmOMfRCyEYLgz53ARZo'
                                    b'ugmEu_edeW-0j2DVRY"}}-AADAA6Z50BRlXby_uSdkqbybLXds-5OMwQil4miux1'
                                    b'sRxJkiD3kRS4HuCpv5m-wwsPHWwn_Ku5xB2P--NJ1pl7KXjAQABDjMdRtemkn9oy'
                                    b'kLFo9MBwZsS85hGd1yaMMdFb_P1FY8_PZcHBVTc2iF5Bd6T2rGorwS-ChRa24bxU'
                                    b'rkemWD1DAACpxUYq2zrFAlMdWuxdaYTqvh12pgk4Ba-vllsaZP5ct5HcOtJw47B6'
                                    b'cVLcEePwEHk6jHlSoDGgH2YiyOwPbgSBQ{"v":"KERI10JSON000105_","i":"E'
                                    b'4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"1","t":"vrc","'
                                    b'd":"E8MU3qwR6gzbMUqEXh0CgG4k3k4WKkk9hM0iaVeCmG7E","a":{"i":"E_T2'
                                    b'_p83_gRSuAYvGhqV3S0JzYEF2dIa-OCPLbIhBO7Y","s":"0","d":"EFSbLZkTm'
                                    b'OMfRCyEYLgz53ARZougmEu_edeW-0j2DVRY"}}-AADAAPLMNHELcDDuPT1gyI9_T'
                                    b'EBM6FRji2xmc0iBfNBwoKJttbJfeQhH41y-ayubtyhyMzHaqrq-WXaNQkpnzTTOP'
                                    b'BAABUawpt1Nd7GR9rTwPD4ucT-M7Vy1xuxGlgRf9pgkOcXBBbhomjjEpz3aid9PP'
                                    b'2vWeJ_rvw7W5rgrTJ38Q2v8bDwACoHNjlZ-IZ1K9opgeu33TNIFBd3rNW_gKO_bF'
                                    b'a-t2GYwOzlWoDlzF7kSRQnVKlXMeVrLBe3uwO6PjYjeZdUSlDg{"v":"KERI10JS'
                                    b'ON000105_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s'
                                    b'":"2","t":"vrc","d":"EO2hh7xg29y3i7uywQ_n0g7vk0W1oGiErUY9QpGjSUh'
                                    b'c","a":{"i":"E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-OCPLbIhBO7Y","s":"'
                                    b'0","d":"EFSbLZkTmOMfRCyEYLgz53ARZougmEu_edeW-0j2DVRY"}}-AADAA7JJ'
                                    b'AxJL3nhVur7YboCK2zPSmx_AaYDYeN7UsvoKcZKrYbuScUje_qfx_e9z1SM4tm8b'
                                    b'UbYJnLXTz8dOta9ZiDwABi7dsjnldn7E-L56Rlz4ZWp8XC5y8v7h4XRoZp2sO69H'
                                    b'84dhyRM27UE9_egCWQZJ_MHJKVA5g2s0hXmXvjSKrAQACo0JcZmUhiNBfb_3bBwg'
                                    b'X7KfN52vmazAzEFgJlr8wNfXSvF6rA5lED4J1EWuEnhA00vUHQqPrjk78nnRBBZl'
                                    b'VAA{"v":"KERI10JSON000105_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW'
                                    b'5Wapj3LcQ8CT4","s":"3","t":"vrc","d":"EQI0EXdK6WvQae17PBWDUkMOdO'
                                    b'iTPpx48oMSYTUYsCl0","a":{"i":"E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-O'
                                    b'CPLbIhBO7Y","s":"0","d":"EFSbLZkTmOMfRCyEYLgz53ARZougmEu_edeW-0j'
                                    b'2DVRY"}}-AADAAG1L04T2jREp2pizW-jQ0tglZ8I4CDNoKx4bN2K0ztuf_0ywQ29'
                                    b'p2kFkBVZaRPwljOZlUzJqlPU6P2R-IVORJBQAB2ss-isfVr2WpdCWwNxO_9N75eJ'
                                    b'K-2CZp1J-DicWd8FqziZIc-kAmxNBD9TjxfuYn7pQmXnaWF7g4RhCLJGBuDAACrx'
                                    b'gx3QlrBs-g369i807ntd8rGWGC4WGrrdy60cPy9hjrP10qjDtSTwa2UZPNVEUZol'
                                    b'M-lHsFqoNhjeaHmg_mDA{"v":"KERI10JSON000105_","i":"E4ReNhXtuh4DAK'
                                    b'e4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"4","t":"vrc","d":"EvrAC5XVQ'
                                    b'yu01ZuKfq1wiR0kXF2j8TjrCg4QyA0LVjKk","a":{"i":"E_T2_p83_gRSuAYvG'
                                    b'hqV3S0JzYEF2dIa-OCPLbIhBO7Y","s":"0","d":"EFSbLZkTmOMfRCyEYLgz53'
                                    b'ARZougmEu_edeW-0j2DVRY"}}-AADAAh0E0mltmkUz1_TXMirWFa67IGAaK7fThh'
                                    b'rJ8TQyuhY7usunzf8VtWfaaLBQSpofhgppsMlf3zZxDS1g6t-7PCgABECiScuPby'
                                    b'_LbGw5s6qNTJQm2m6Dqbsig7sRdk841XWU6hV3MlD-k_SriiPEJWMAWDmY74lM-U'
                                    b'iNDvnmN4OAJCAACSc48sfSvNtYByMlUQsMPdEsDw5Z6oDX4jlZ9F5eCMcRvYWWAp'
                                    b'AD-OOi85JTIiW3y3nSdbfyt4vS6YvroA68MAQ{"v":"KERI10JSON000105_","i'
                                    b'":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"5","t":"vr'
                                    b'c","d":"EwmQtlcszNoEIDfqD-Zih3N6o5B3humRKvBBln2juTEM","a":{"i":"'
                                    b'E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-OCPLbIhBO7Y","s":"0","d":"EFSbL'
                                    b'ZkTmOMfRCyEYLgz53ARZougmEu_edeW-0j2DVRY"}}-AADAAgXtG2I3AxvU5yHKz'
                                    b'fucOKOvxeKWwChKQvEQJtJnz9iIpsXqyyrgRfOyoyjhk73D-E3FbDg_3k1XK_3i-'
                                    b'yDWeAQAByUVjq4Y_sMWi9iqqWXTo2ES5pBMlBgJbAY3h61aJElQdCIxr2ldx_BSq'
                                    b'4vA-FlELEBUkSbeHnHGXeFfVi6AjCwAC6GmjxPFclVsY7smEcpmptQnZgET9LUO6'
                                    b'06SzhkCaGCe1jR2KZ3vNsgitA_7OQ_VDipLwoWGv_Kz2YnUkjKFsCw{"v":"KERI'
                                    b'10JSON000105_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4'
                                    b'","s":"6","t":"vrc","d":"EvFMG33kYq7JGOY1fWl1_VqfAe0MfPO3IhasTID'
                                    b'kayaY","a":{"i":"E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-OCPLbIhBO7Y","'
                                    b's":"0","d":"EFSbLZkTmOMfRCyEYLgz53ARZougmEu_edeW-0j2DVRY"}}-AADA'
                                    b'A9U_Kq0GNM1fFq1Vgp937kHkwxSBn4nT8UciTepjjOdOAR-hvsLCxQx2V2pbyQo3'
                                    b'fubs6mPd6TQ4ZUmXNrtxmBwABuFO678xi0JuYyQWnSOtOVXABknvRo6-0EWFCv7h'
                                    b'xucmqgE6Je2R4120G3nFsJ_ImTjkDibQU8m7CYBGcFh-hAQACBUqcpzMYX373ePK'
                                    b'sfKBjt9aXO2vkl9jAb5vBHFYc0h5r-pGL2TIgoyfMPMAf0zFrsKnDdmN0HmSaE1O'
                                    b'sP2hmDA')

        # Play camMsgs to Deb
        # create non-local kevery for Deb to process msgs from Cam
        debKevery = eventing.Kevery(kevers=debHab.kevers,
                                    db=debHab.db,
                                    framed=True,
                                    opre=debHab.pre,
                                    local=False)
        debKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in debKevery.kevers
        assert debKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Cam's events by processing Deb's cues
        debCamVrcs = debHab.processCues(debKevery.cues)
        assert debCamVrcs == bytearray(b'{"v":"KERI10JSON000105_","i":"E_T2_p83_gRSuAYvGhqV3S0JzYEF2dIa-O'
                                    b'CPLbIhBO7Y","s":"0","t":"vrc","d":"EFSbLZkTmOMfRCyEYLgz53ARZougm'
                                    b'Eu_edeW-0j2DVRY","a":{"i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3'
                                    b'LcQ8CT4","s":"2","d":"EO2hh7xg29y3i7uywQ_n0g7vk0W1oGiErUY9QpGjSU'
                                    b'hc"}}-AADAAmZij1Eyp2LOvVf0EevWsIIUiE9OEbhV5MvWvGHWzlvmzoaJ71KxSL'
                                    b'dMkqWG6yPyBLJjVNds_SQVVFnbpoPKwAAABNLo-_rnW2tfAu9GaP6XS2lyHTLUkG'
                                    b'TGKwjBA6hepC-E8XEiFMQekheKx-ir6xWxRPF9vBZuWwZKIqtwR2EwcDwACeHbCs'
                                    b'HbSgD7m9bWGB2ZCN8jxAfrbCMRGWersAEXqtdtkYT0Xxg33W61o5IffZjWxsHY_i'
                                    b'JQOPDVF3tA4DniWBg')

        # Play disjoints debCamVrcs to Cam
        camKevery.processOne(ims=bytearray(debCamVrcs))  # give copy to process

        # Play debMsgs to Bev
        # create non-local kevery for Bev to process msgs from Deb
        bevKevery = eventing.Kevery(kevers=bevHab.kevers,
                                    db=bevHab.db,
                                    framed=True,
                                    opre=bevHab.pre,
                                    local=False)
        bevKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in bevKevery.kevers
        assert bevKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(bevKevery.cues) == 7

        # get disjoints receipts (rcts) from Bev of Deb's events by processing Bevs's cues
        bevMsgs = bevHab.processCues(bevKevery.cues)
        assert bevMsgs == bytearray(b'{"v":"KERI10JSON0000ba_","i":"BaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_'
                                    b'RBsuNtZHQg","s":"0","t":"icp","kt":"1","k":["BaYh8uaASuDjMUd8_Bo'
                                    b'NyQs3GwupzmJL8_RBsuNtZHQg"],"n":"","wt":"0","w":[],"c":[]}-AABAA'
                                    b'dRmfIn6JHxhpyooEf22kqZxsa4OTpl9DVL6GDWNWlyk-MGQeo2pU5mI288Jl8SwP'
                                    b'PbTGbdeKdWUfG15bjil8AA{"v":"KERI10JSON000091_","i":"E4ReNhXtuh4D'
                                    b'AKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"0","t":"rct","d":"Egd_fi2'
                                    b'QDtfjjdB5p9tT6QCHuBsSWUwQP6AbarcjLgw0"}-CABBaYh8uaASuDjMUd8_BoNy'
                                    b'Qs3GwupzmJL8_RBsuNtZHQg0B6Z50BRlXby_uSdkqbybLXds-5OMwQil4miux1sR'
                                    b'xJkiD3kRS4HuCpv5m-wwsPHWwn_Ku5xB2P--NJ1pl7KXjAQ{"v":"KERI10JSON0'
                                    b'00091_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"'
                                    b'1","t":"rct","d":"E8MU3qwR6gzbMUqEXh0CgG4k3k4WKkk9hM0iaVeCmG7E"}'
                                    b'-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0BPLMNHELcDDuPT1'
                                    b'gyI9_TEBM6FRji2xmc0iBfNBwoKJttbJfeQhH41y-ayubtyhyMzHaqrq-WXaNQkp'
                                    b'nzTTOPBA{"v":"KERI10JSON000091_","i":"E4ReNhXtuh4DAKe4_qcX__uF70'
                                    b'MnOvW5Wapj3LcQ8CT4","s":"2","t":"rct","d":"EO2hh7xg29y3i7uywQ_n0'
                                    b'g7vk0W1oGiErUY9QpGjSUhc"}-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_R'
                                    b'BsuNtZHQg0B7JJAxJL3nhVur7YboCK2zPSmx_AaYDYeN7UsvoKcZKrYbuScUje_q'
                                    b'fx_e9z1SM4tm8bUbYJnLXTz8dOta9ZiDw{"v":"KERI10JSON000091_","i":"E'
                                    b'4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"3","t":"rct","'
                                    b'd":"EQI0EXdK6WvQae17PBWDUkMOdOiTPpx48oMSYTUYsCl0"}-CABBaYh8uaASu'
                                    b'DjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0BG1L04T2jREp2pizW-jQ0tglZ8I4C'
                                    b'DNoKx4bN2K0ztuf_0ywQ29p2kFkBVZaRPwljOZlUzJqlPU6P2R-IVORJBQ{"v":"'
                                    b'KERI10JSON000091_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ'
                                    b'8CT4","s":"4","t":"rct","d":"EvrAC5XVQyu01ZuKfq1wiR0kXF2j8TjrCg4'
                                    b'QyA0LVjKk"}-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0Bh0E'
                                    b'0mltmkUz1_TXMirWFa67IGAaK7fThhrJ8TQyuhY7usunzf8VtWfaaLBQSpofhgpp'
                                    b'sMlf3zZxDS1g6t-7PCg{"v":"KERI10JSON000091_","i":"E4ReNhXtuh4DAKe'
                                    b'4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"5","t":"rct","d":"EwmQtlcszN'
                                    b'oEIDfqD-Zih3N6o5B3humRKvBBln2juTEM"}-CABBaYh8uaASuDjMUd8_BoNyQs3'
                                    b'GwupzmJL8_RBsuNtZHQg0BgXtG2I3AxvU5yHKzfucOKOvxeKWwChKQvEQJtJnz9i'
                                    b'IpsXqyyrgRfOyoyjhk73D-E3FbDg_3k1XK_3i-yDWeAQ{"v":"KERI10JSON0000'
                                    b'91_","i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3LcQ8CT4","s":"6",'
                                    b'"t":"rct","d":"EvFMG33kYq7JGOY1fWl1_VqfAe0MfPO3IhasTIDkayaY"}-CA'
                                    b'BBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0B9U_Kq0GNM1fFq1Vgp'
                                    b'937kHkwxSBn4nT8UciTepjjOdOAR-hvsLCxQx2V2pbyQo3fubs6mPd6TQ4ZUmXNr'
                                    b'txmBw')

        # Play bevMsgs to Deb
        debKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in debKevery.kevers
        assert debKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Bev's events by processing Deb's cues
        debBevVrcs = debHab.processCues(debKevery.cues)
        assert debBevVrcs == bytearray(b'{"v":"KERI10JSON000105_","i":"BaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_'
                                        b'RBsuNtZHQg","s":"0","t":"vrc","d":"EtTEz3ofbRmq4qeoKSc5uYWUhxeZa'
                                        b'8OjmCkZnesb0gws","a":{"i":"E4ReNhXtuh4DAKe4_qcX__uF70MnOvW5Wapj3'
                                        b'LcQ8CT4","s":"2","d":"EO2hh7xg29y3i7uywQ_n0g7vk0W1oGiErUY9QpGjSU'
                                        b'hc"}}-AADAAk0o2XsjZ8tfbaCKZZcSvmYdUxmqWMVMH1PLD6081VC04_c_nIXHfy'
                                        b'G5gRVXDsoncZk7euiZ9Q60E7rGi-FOLBQAB6xngS-To8PAVjMSz0bv4oqju1vmke'
                                        b'Hwq7EQOWMvM5WeKzLOwpgnCxCyZkYCzXU6Yyym9_TJOxL144wRVS92sAQACSG9_s'
                                        b'dTl_1t_bFi-fnkBwX7QLvB53NDNQShHwUjdvxupDMUJkx6QLwsUH_SwybCFO0rX5'
                                        b'K5TQKbTKbQ9F9TcAg')


        # Play disjoints debBevVrcs to Bev
        bevKevery.processOne(ims=bytearray(debBevVrcs))  # give copy to process

        # now setup conjoint replay

        # Replay Deb's First Seen Events with receipts (vrcs and rcts) from both Cam and Bev
        # datetime is different in each run in the fse attachment in clone replay
        # so we either have to force dts in db or we parse in pieces
        debFelMsgs = bytearray()
        fn = 0
        cloner = debHab.db.cloneIter(pre=debHab.pre, fn=fn)  # create iterator
        msg = next(cloner)  # get zeroth event with attachments
        assert len(msg) == 1416
        debFelMsgs.extend(msg)

        # parse msg
        serder = coring.Serder(raw=msg)
        assert serder.raw == debHab.iserder.raw
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.icp
        del msg[:len(serder.raw)]
        assert len(msg) == 1076

        counter = coring.Counter(qb64b=msg)  # attachment length quadlets counter
        assert counter.code == coring.CtrDex.AttachedMaterialQuadlets
        assert counter.count == (len(msg) - len(counter.qb64b)) // 4 ==  268
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1072 == 268 *  4

        counter = coring.Counter(qb64b=msg)  # indexed signatures counter
        assert counter.code == coring.CtrDex.ControllerIdxSigs
        assert counter.count == 3  #  multisig deb
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1068

        for i in range(counter.count):  # parse signatures
            siger = coring.Siger(qb64b=msg)
            del msg[:len(siger.qb64b)]
        assert len(msg) == 1068 - 3 * len(siger.qb64b) == 804

        counter = coring.Counter(qb64b=msg)  # trans receipt (vrc) counter
        assert counter.code == coring.CtrDex.TransReceiptQuadruples
        assert counter.count == 3  #  multisig cam
        del msg[:len(counter.qb64b)]
        assert len(msg) == 800

        for i in range(counter.count):  # parse receipt quadruples
            prefixer, seqner, diger, siger = eventing.deTransReceiptQuadruple(msg, strip=True)
        assert len(msg) == 800 - 3 * (len(prefixer.qb64b) + len(seqner.qb64b) +
                                len(diger.qb64b) + len(siger.qb64b)) == 200

        counter = coring.Counter(qb64b=msg)  # nontrans receipt (rct) counter
        assert counter.code == coring.CtrDex.NonTransReceiptCouples
        assert counter.count == 1  #  single sig bev
        del msg[:len(counter.qb64b)]
        assert len(msg) == 196

        for i in range(counter.count):  # parse receipt couples
            prefixer, cigar = eventing.deReceiptCouple(msg, strip=True)
        assert len(msg) == 196 - 1 * (len(prefixer.qb64b) + len(cigar.qb64b)) == 64

        counter = coring.Counter(qb64b=msg)  # first seen replay couple counter
        assert counter.code == coring.CtrDex.FirstSeenReplayCouples
        assert counter.count == 1
        del msg[:len(counter.qb64b)]
        assert len(msg) == 60

        seqner = coring.Seqner(qb64b=msg)
        assert seqner.sn == fn == 0
        del msg[:len(seqner.qb64b)]
        assert len(msg) == 36  # 24 less

        dater = coring.Dater(qb64b=msg)
        assert (helping.fromIso8601(helping.nowIso8601()) -
                helping.fromIso8601(dater.dts)) > datetime.timedelta()
        del msg[:len(dater.qb64b)]
        assert len(msg) == 0  # 36 less

        cloner.close()  # must close or get lmdb error upon with exit
        """Exception ignored in: <generator object LMDBer.getAllOrdItemPreIter at 0x106fe1c10>
        Traceback (most recent call last):
        File "/Users/Load/Data/Code/public/keripy/src/keri/db/dbing.py", line 512, in getAllOrdItemPreIter
        yield (cn, bytes(val))  # (on, dig) of event
        lmdb.Error: Attempt to operate on closed/deleted/dropped object.
        """

        fn += 1
        cloner = debHab.db.cloneIter(pre=debHab.pre, fn=fn)  # create iterator not at 0
        msg = next(cloner)  # next event with attachments
        assert len(msg) == 1228
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.ixn
        debFelMsgs.extend(msg)

        fn += 1
        msg = next(cloner)  # get zeroth event with attachments
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.rot
        assert len(msg) == 1476
        assert ([verfer.qb64 for verfer in serder.verfers] ==
                [verfer.qb64 for verfer in debHab.kever.verfers])
        debFelMsgs.extend(msg)

        fn += 1
        while (fn <= 6 ):
            msg = next(cloner)  # get zeroth event with attachments
            serder = coring.Serder(raw=msg)
            assert serder.sn == fn  # no recovery forks so sn == fn
            assert serder.ked["t"] == coring.Ilks.ixn
            assert len(msg) == 1228
            debFelMsgs.extend(msg)
            fn += 1

        assert len(debFelMsgs) == 9032
        cloner.close()  # must close or get lmdb error upon with exit

        msgs = debHab.replay()
        assert msgs == debFelMsgs

        # Play Cam's messages to Bev
        bevKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in bevKevery.kevers
        assert bevKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(bevKevery.cues) == 1

        # Play Bev's messages to Cam
        camKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in camKevery.kevers
        assert camKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(camKevery.cues) == 1

        camDebFelMsgs = camHab.replay(pre=debHab.pre)
        bevDebFelMsgs = bevHab.replay(pre=debHab.pre)

        assert len(bevDebFelMsgs) == len(camDebFelMsgs) == len(debFelMsgs) == 9032

        # create non-local kevery for Art to process conjoint replay msgs from Deb
        artKevery = eventing.Kevery(kevers=artHab.kevers,
                                        db=artHab.db,
                                        framed=True,
                                        opre=artHab.pre,
                                        local=False)
        # process Cam's inception so Art will proces Cam's vrcs without escrowing
        camIcpMsg = camHab.makeOwnInception()
        artKevery.process(ims=bytearray(camIcpMsg))
        assert camHab.pre in artKevery.kevers
        assert len(artKevery.cues) == 1

        artKevery.process(ims=bytearray(debFelMsgs), cloned=True)  # give copy to process
        assert debHab.pre in artKevery.kevers
        assert artKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(artKevery.cues) == 8
        artDebFelMsgs = artHab.replay(pre=debHab.pre)
        assert len(artDebFelMsgs) == 9032


    assert not os.path.exists(artKS.path)
    assert not os.path.exists(artDB.path)
    assert not os.path.exists(bevKS.path)
    assert not os.path.exists(bevDB.path)
    assert not os.path.exists(camKS.path)
    assert not os.path.exists(camDB.path)
    assert not os.path.exists(debKS.path)
    assert not os.path.exists(debDB.path)

    """End Test"""
示例#16
0
def test_issuing():
    sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64

    with basing.openDB(name="sid") as sidDB, \
            keeping.openKS(name="sid") as sidKS, \
            basing.openDB(name="red") as redDB, \
            openPocket(name="red") as redPDB:
        limit = 1.0
        tock = 1.0
        doist = doing.Doist(limit=limit, tock=tock)

        sidHab = habbing.Habitat(ks=sidKS, db=sidDB, salt=sidSalt, temp=True)
        sidPre = sidHab.pre
        assert sidPre == "E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E"

        sidIcpMsg = sidHab.makeOwnInception()

        redKvy = eventing.Kevery(db=redDB)
        parsing.Parser().parse(ims=bytearray(sidIcpMsg), kvy=redKvy)
        assert redKvy.kevers[sidPre].sn == 0  # accepted event

        sed = dict()
        sed["$id"] = ""
        sed["$schema"] = "http://json-schema.org/draft-07/schema#"
        sed.update(
            dict(type="object",
                 properties=dict(id=dict(type="string"),
                                 lei=dict(type="string"))))

        schemer = scheming.Schemer(sed=sed, code=coring.MtrDex.Blake3_256)
        assert schemer.said == "EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY"

        cache = scheming.CacheResolver()
        cache.add(schemer.said, schemer.raw)
        jsonSchema = JSONSchema(resolver=cache)

        # Create Red's wallet and Issue Handler for receiving the credential
        redWallet = Wallet(hab=sidHab, db=redPDB)
        redIssueHandler = IssueHandler(wallet=redWallet, typ=jsonSchema)
        redExc = exchanging.Exchanger(hab=sidHab,
                                      tymth=doist.tymen(),
                                      handlers=[redIssueHandler])

        # Build the credential subject and then the Credentialer for the full credential
        credSubject = dict(
            id=
            "did:keri:Efaavv0oadfghasdfn443fhbyyr4v",  # this needs to be generated from a KEL
            lei="254900OPPU84GM83MG36",
            issuanceDate="2021-06-27T21:26:21.233257+00:00",
        )

        creder = credential(issuer=sidHab.pre,
                            schema=schemer.said,
                            subject=credSubject,
                            typ=jsonSchema)

        assert creder.said == "EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM"

        msg = sidHab.endorse(serder=creder)
        assert msg == (
            b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",'
            b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",'
            b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",'
            b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}-VA0-FABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE'
            b'-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw-AxDNI7_ZmaI'
            b'-AABAA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA'
        )

        # Create the issue credential payload
        pl = dict(vc=[envelope(msg, typ=jsonSchema)])

        # Create the `exn` message for issue credential
        sidExcSrdr = exchanging.exchange(route="/credential/issue", payload=pl)
        excMsg = sidHab.sanction(sidExcSrdr)

        # Parse the exn issue credential message on Red's side
        parsing.Parser().parse(ims=bytearray(excMsg), kvy=redKvy, exc=redExc)
        doist.do(doers=[redExc])
        assert doist.tyme == limit

        ser = (
            b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",'
            b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",'
            b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",'
            b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}')
        sig0 = (
            b'AA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA'
        )

        # verify we can load serialized VC by SAID
        key = creder.said.encode("utf-8")
        assert redPDB.getSers(key) == ser

        # verify the signature
        sigs = redPDB.getSigs(key)
        assert len(sigs) == 1
        assert sigs[0] == sig0

        # verify we can look up credential by Schema SAID
        schema = redPDB.getSchms(schemer.saider.qb64b)
        assert len(schema) == 1
        assert schema[0] == key
示例#17
0
def test_witness():
    """
    Test event validation logic with witnesses

    cam is controller
    van is validator
    wes is a witness
    wok is a witness
    wam is a witness

    """
    salt = coring.Salter(raw=b'abcdef0123456789').qb64

    with dbing.openDB(name="cam") as camDB, keeping.openKS(name="cam") as camKS, \
         dbing.openDB(name="van") as vanDB, keeping.openKS(name="van") as vanKS, \
         dbing.openDB(name="wes") as wesDB, keeping.openKS(name="wes") as wesKS, \
         dbing.openDB(name="wok") as wokDB, keeping.openKS(name="wok") as wokKS, \
         dbing.openDB(name="wam") as wamDB, keeping.openKS(name="wam") as wamKS, \
         dbing.openDB(name="wil") as wilDB, keeping.openKS(name="wil") as wilKS:

        # witnesses first so can setup inception event for cam
        wsith = 1
        # setup Wes's habitat nontrans
        # Wes's receipts will be rcts with a receipt couple attached

        wesHab = directing.Habitat(name='wes',
                                   ks=wesKS,
                                   db=wesDB,
                                   isith=wsith,
                                   icount=1,
                                   salt=salt,
                                   transferable=False,
                                   temp=True)  # stem is .name
        assert wesHab.ks == wesKS
        assert wesHab.db == wesDB
        assert not wesHab.kever.prefixer.transferable
        # create non-local kevery for Wes to process nonlocal msgs
        wesKvy = eventing.Kevery(kevers=wesHab.kevers,
                                 db=wesHab.db,
                                 framed=True,
                                 opre=wesHab.pre,
                                 local=False)

        # setup Wok's habitat nontrans
        # Wok's receipts will be rcts with a receipt couple attached
        wokHab = directing.Habitat(name='wok',
                                   ks=wokKS,
                                   db=wokDB,
                                   isith=wsith,
                                   icount=1,
                                   salt=salt,
                                   transferable=False,
                                   temp=True)  # stem is .name
        assert wokHab.ks == wokKS
        assert wokHab.db == wokDB
        assert not wokHab.kever.prefixer.transferable
        # create non-local kevery for Wok to process nonlocal msgs
        wokKvy = eventing.Kevery(kevers=wokHab.kevers,
                                 db=wokHab.db,
                                 framed=True,
                                 opre=wokHab.pre,
                                 local=False)

        # setup Wam's habitat nontrans
        # Wams's receipts will be rcts with a receipt couple attached
        wamHab = directing.Habitat(name='wam',
                                   ks=wamKS,
                                   db=wamDB,
                                   isith=wsith,
                                   icount=1,
                                   salt=salt,
                                   transferable=False,
                                   temp=True)  # stem is .name
        assert wamHab.ks == wamKS
        assert wamHab.db == wamDB
        assert not wamHab.kever.prefixer.transferable
        # create non-local kevery for Wam to process nonlocal msgs
        wamKvy = eventing.Kevery(kevers=wamHab.kevers,
                                 db=wamHab.db,
                                 framed=True,
                                 opre=wamHab.pre,
                                 local=False)

        # setup Wil's habitat nontrans
        # Wil's receipts will be rcts with a receipt couple attached
        wilHab = directing.Habitat(name='wil',
                                   ks=wilKS,
                                   db=wilDB,
                                   isith=wsith,
                                   icount=1,
                                   salt=salt,
                                   transferable=False,
                                   temp=True)  # stem is .name
        assert wilHab.ks == wilKS
        assert wilHab.db == wilDB
        assert not wilHab.kever.prefixer.transferable
        # create non-local kevery for Wam to process nonlocal msgs
        wilKvy = eventing.Kevery(kevers=wilHab.kevers,
                                 db=wilHab.db,
                                 framed=True,
                                 opre=wilHab.pre,
                                 local=False)

        # setup Cam's habitat trans multisig
        wits = [wesHab.pre, wokHab.pre, wamHab.pre]
        csith = 2  # hex str of threshold int
        camHab = directing.Habitat(name='cam',
                                   ks=camKS,
                                   db=camDB,
                                   isith=csith,
                                   icount=3,
                                   toad=2,
                                   wits=wits,
                                   salt=salt,
                                   temp=True)  # stem is .name
        assert camHab.ks == camKS
        assert camHab.db == camDB
        assert camHab.kever.prefixer.transferable
        for werfer in camHab.iserder.werfers:
            assert werfer.qb64 in wits
        assert camHab.kever.wits == wits
        assert camHab.kever.toad == 2
        assert camHab.kever.sn == 0

        # create non-local kevery for Cam to process onlocal msgs
        camKvy = eventing.Kevery(kevers=camHab.kevers,
                                 db=camHab.db,
                                 framed=True,
                                 opre=camHab.pre,
                                 local=False)

        # setup Van's habitat trans multisig
        vsith = 2  # two of three signing threshold
        vanHab = directing.Habitat(name='van',
                                   ks=vanKS,
                                   db=vanDB,
                                   isith=vsith,
                                   icount=3,
                                   salt=salt,
                                   temp=True)  # stem is .name
        assert vanHab.ks == vanKS
        assert vanHab.db == vanDB
        assert vanHab.kever.prefixer.transferable
        # create non-local kevery for Van to process nonlocal msgs
        vanKvy = eventing.Kevery(kevers=vanHab.kevers,
                                 db=vanHab.db,
                                 framed=True,
                                 opre=vanHab.pre,
                                 local=False)

        # make list so easier to batch
        camWitKvys = [wesKvy, wokKvy, wamKvy]
        camWitHabs = [wesHab, wokHab, wamHab]

        # Create Cam inception and send to each of Cam's witnesses
        camIcpMsg = camHab.makeOwnInception()
        rctMsgs = []  # list of receipts from each witness
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(ims=bytearray(
                camIcpMsg))  # send copy of cam icp msg to witness
            assert kvy.kevers[camHab.pre].sn == 0  # accepted event
            assert len(kvy.cues) == 1  # queued receipt cue
            hab = camWitHabs[i]
            rctMsg = hab.processCues(kvy.cues)  # process cue returns rct msg
            assert len(rctMsg) == 559
            rctMsgs.append(rctMsg)

        for msg in rctMsgs:  # process rct msgs from all witnesses
            camKvy.process(ims=bytearray(msg))  # make copy
        for hab in camWitHabs:
            assert hab.pre in camKvy.kevers

        # get from Cam database copies of witness receipts received by Cam
        # and send to witnesses so all witnesses have full set of receipts
        # from all other witnesses
        # reply one event or receipt one event with all witness attachments
        dgkey = dbing.dgKey(pre=camHab.pre, dig=camHab.kever.serder.dig)
        wigs = camHab.db.getWigs(dgkey)
        assert len(wigs) == 3
        wigers = [coring.Siger(qb64b=bytes(wig)) for wig in wigs]
        rserder = eventing.receipt(pre=camHab.pre,
                                   sn=camHab.kever.sn,
                                   dig=camHab.kever.serder.dig)
        camIcpWitRctMsg = eventing.messagize(serder=rserder, wigers=wigers)
        assert len(camIcpWitRctMsg) == 413
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(
                ims=bytearray(camIcpWitRctMsg))  # send copy of witness rcts
            assert len(kvy.db.getWigs(dgkey)) == 3  # fully witnessed
            assert len(kvy.cues) == 0  # no cues

        # send Cam icp and witness rcts to Van
        vanKvy.process(
            ims=bytearray(camIcpMsg))  # should escrow since not witnesses
        assert camHab.pre not in vanKvy.kevers
        vanKvy.process(ims=bytearray(camIcpWitRctMsg))
        vanKvy.processEscrows()
        assert camHab.pre in vanKvy.kevers
        vcKvr = vanKvy.kevers[camHab.pre]
        assert vcKvr.sn == 0
        assert vcKvr.wits == wits

        # Create Cam ixn and send to each of Cam's witnesses
        camIxnMsg = camHab.interact()
        rctMsgs = []  # list of receipts from each witness
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(ims=bytearray(
                camIxnMsg))  # send copy of cam icp msg to witness
            assert kvy.kevers[camHab.pre].sn == 1  # accepted event
            assert len(kvy.cues) == 1  # queued receipt cue
            hab = camWitHabs[i]
            rctMsg = hab.processCues(kvy.cues)  # process cue returns rct msg
            assert len(rctMsg) == 281
            rctMsgs.append(rctMsg)

        for msg in rctMsgs:  # process rct msgs from all witnesses
            camKvy.process(ims=bytearray(msg))  # make copy
        for hab in camWitHabs:
            assert hab.pre in camKvy.kevers

        # get from Cam database copies of witness receipts received by Cam
        # and send to witnesses so all witnesses have full set of receipts
        # from all other witnesses
        # reply one event or receipt one event with all witness attachments
        dgkey = dbing.dgKey(pre=camHab.pre, dig=camHab.kever.serder.dig)
        wigs = camHab.db.getWigs(dgkey)
        assert len(wigs) == 3
        wigers = [coring.Siger(qb64b=bytes(wig)) for wig in wigs]
        rserder = eventing.receipt(pre=camHab.pre,
                                   sn=camHab.kever.sn,
                                   dig=camHab.kever.serder.dig)
        camIxnWitRctMsg = eventing.messagize(serder=rserder, wigers=wigers)
        assert len(camIxnWitRctMsg) == 413
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(
                ims=bytearray(camIxnWitRctMsg))  # send copy of witness rcts
            assert len(kvy.db.getWigs(dgkey)) == 3  # fully witnessed
            assert len(kvy.cues) == 0  # no cues

        # send Cam ixn's witness rcts to Van first then send Cam ixn
        vanKvy.process(ims=bytearray(camIxnWitRctMsg))
        vanKvy.processEscrows()
        assert vcKvr.sn == 0
        vanKvy.process(
            ims=bytearray(camIxnMsg))  # should escrow since not witnesses
        assert vcKvr.sn == 0
        vanKvy.processEscrows()
        assert vcKvr.sn == 1

        # Cam replace Wok with Wil as a witness.
        # Cam update Wil all event witnessed events for Cam by replay
        # Cam update itself with Wil receipts including Wils inception
        camReplayMsg = camHab.replay()
        assert len(camReplayMsg) == 1824
        wilKvy.process(ims=bytearray(camReplayMsg))
        assert camHab.pre in wilKvy.kevers
        assert wilKvy.kevers[camHab.pre].sn == 1  # asscepted both events
        assert len(wilKvy.cues) == 2
        wilRctMsg = wilHab.processCues(
            wilKvy.cues)  # process cue returns rct msg
        assert len(wilKvy.cues) == 0
        camKvy.process(ims=bytearray(wilRctMsg))  # make copy
        assert wilHab.pre in camKvy.kevers

        # Cam rotation with witness rotation
        camRotMsg = camHab.rotate(toad=2, cuts=[wokHab.pre], adds=[wilHab.pre])
        assert camHab.kever.wits == [wesHab.pre, wamHab.pre, wilHab.pre]
        assert camHab.kever.toad == 2
        assert camHab.kever.sn == 2

        # update lists of witness kvys and habs
        camWitKvys = [wesKvy, wamKvy, wilKvy]
        camWitHabs = [wesHab, wamHab, wilHab]

        rctMsgs = []  # list of receipt msgs from each witness
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(
                ims=bytearray(camRotMsg))  # send copy of cam msg to witness
            assert kvy.kevers[camHab.pre].sn == 2  # accepted event
            assert len(kvy.cues) == 1  # queued receipt cue
            hab = camWitHabs[i]
            rctMsg = hab.processCues(kvy.cues)  # process cue returns rct msg
            assert len(rctMsg) == 281
            rctMsgs.append(rctMsg)

        for msg in rctMsgs:  # process rct msgs from all witnesses
            camKvy.process(ims=bytearray(msg))  # make copy
        for hab in camWitHabs:
            assert hab.pre in camKvy.kevers

        # get from Cam database copies of witness receipts received by Cam
        # and send to witnesses so all witnesses have full set of receipts
        # from all other witnesses
        # reply one event or receipt one event with all witness attachments
        dgkey = dbing.dgKey(pre=camHab.pre, dig=camHab.kever.serder.dig)
        wigs = camHab.db.getWigs(dgkey)
        assert len(wigs) == 3
        wigers = [coring.Siger(qb64b=bytes(wig)) for wig in wigs]
        rserder = eventing.receipt(pre=camHab.pre,
                                   sn=camHab.kever.sn,
                                   dig=camHab.kever.serder.dig)
        camRotWitRctMsg = eventing.messagize(serder=rserder, wigers=wigers)
        assert len(camRotWitRctMsg) == 413
        for i in range(len(camWitKvys)):
            kvy = camWitKvys[i]
            kvy.process(
                ims=bytearray(camRotWitRctMsg))  # send copy of witness rcts
            assert len(kvy.db.getWigs(dgkey)) == 3  # fully witnessed
            assert len(kvy.cues) == 0  # no cues

        # send Cam's rot and wit receipts to Van
        #vanKvy.process(ims=bytearray(camRotMsg))  # should escrow since not witnesses
        #vanKvy.process(ims=bytearray(camRotWitRctMsg))
        #vanKvy.processEscrows()
        #assert vcKvr.sn == 2
        #assert vcKvr.wits == camHab.kever.wits

        # send Cam rot's witness rcts to Van first then send Cam rot
        vanKvy.process(ims=bytearray(camRotWitRctMsg))
        vanKvy.processEscrows()
        assert vcKvr.sn == 1
        vanKvy.process(
            ims=bytearray(camRotMsg))  # should escrow since not witnesses
        assert vcKvr.sn == 1
        vanKvy.processEscrows()
        assert vcKvr.sn == 2
        assert vcKvr.wits == camHab.kever.wits

    assert not os.path.exists(wokKS.path)
    assert not os.path.exists(wokDB.path)
    assert not os.path.exists(wesKS.path)
    assert not os.path.exists(wesDB.path)
    assert not os.path.exists(vanKS.path)
    assert not os.path.exists(vanDB.path)
    assert not os.path.exists(camKS.path)
    assert not os.path.exists(camDB.path)
    """End Test"""
示例#18
0
def test_delegation():
    """
    Test creation and validation of delegated identifer prefixes and events

    """
    # bob is the delegator del is bob's delegate

    bobSalt = coring.Salter(raw=b'0123456789abcdef').qb64
    delSalt = coring.Salter(raw=b'abcdef0123456789').qb64

    with dbing.openDB(name="bob") as bobDB, \
          keeping.openKS(name="bob") as bobKS, \
          dbing.openDB(name="del") as delDB, \
          keeping.openKS(name="del") as delKS:

        # Init key pair managers
        bobMgr = keeping.Manager(keeper=bobKS, salt=bobSalt)
        delMgr = keeping.Manager(keeper=delKS, salt=delSalt)

        # Init Keverys
        bobKvy = eventing.Kevery(db=bobDB)
        delKvy = eventing.Kevery(db=delDB)

        # Setup Bob by creating inception event
        verfers, digers, cst, nst = bobMgr.incept(
            stem='bob', temp=True)  # algo default salty and rooted
        bobSrdr = eventing.incept(
            keys=[verfer.qb64 for verfer in verfers],
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64,
            code=coring.MtrDex.Blake3_256)

        bobPre = bobSrdr.ked["i"]
        assert bobPre == 'EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-Uj92Ri7XnFE'

        bobMgr.move(old=verfers[0].qb64,
                    new=bobPre)  # move key pair label to prefix

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=verfers)

        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON0000e6_","i":"EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-U'
            b'j92Ri7XnFE","s":"0","t":"icp","kt":"1","k":["DqI2cOZ06RwGNwCovYU'
            b'WExmdKU983IasmUKMmZflvWdQ"],"n":"E7FuL3Z_KBgt_QAwuZi1lUFNC69wvyH'
            b'SxnMFUsKjZHss","wt":"0","w":[],"c":[]}-AABAAQPFdtnncXLz6dE6A-tXG'
            b'YYK0BHu3I3Pj-G8DxlbzC3yx5MV8yucZILqAA5toZNODnHVHZtPIMkDknqldL4utBQ'
        )

        # apply msg to bob's Kevery
        bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        bobK = bobKvy.kevers[bobPre]
        assert bobK.prefixer.qb64 == bobPre
        assert bobK.serder.diger.qb64 == bobSrdr.dig
        assert bobK.serder.diger.qb64 == 'EvP2kWxEjTMI3auc6x64EpU-nMQZHiBeKeuavcGdRB24'

        # apply msg to del's Kevery
        delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert bobPre in delKvy.kevers

        # Setup Del's inception event assuming that Bob's next event will be an ixn delegating event
        verfers, digers, cst, nst = delMgr.incept(
            stem='del', temp=True)  # algo default salty and rooted

        seal = eventing.SealLocation(i=bobK.prefixer.qb64,
                                     s="{:x}".format(bobK.sn + 1),
                                     t=coring.Ilks.ixn,
                                     p=bobK.serder.diger.qb64)

        assert seal._asdict() == dict(
            i='EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-Uj92Ri7XnFE',
            s='1',
            t='ixn',
            p='EvP2kWxEjTMI3auc6x64EpU-nMQZHiBeKeuavcGdRB24')

        delSrdr = eventing.delcept(
            keys=[verfer.qb64 for verfer in verfers],
            seal=seal,
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64)

        delPre = delSrdr.ked["i"]
        assert delPre == 'ErLe2qWp4VCmDp7v_R01tC-ha13ZEZY0VGcgYtPRhqPs'

        delMgr.move(old=verfers[0].qb64,
                    new=delPre)  # move key pair label to prefix
        assert delSrdr.dig == 'ESDuaqpoI8-HLD8-eLijUMZpXqYFkNArJFDvt3ABYr9I'

        # Now create delegating event
        seal = eventing.SealEvent(i=delPre, s=delSrdr.ked["s"], d=delSrdr.dig)
        bobSrdr = eventing.interact(pre=bobK.prefixer.qb64,
                                    dig=bobK.serder.diger.qb64,
                                    sn=bobK.sn + 1,
                                    data=[seal._asdict()])

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=bobK.verfers)

        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000107_","i":"EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-U'
            b'j92Ri7XnFE","s":"1","t":"ixn","p":"EvP2kWxEjTMI3auc6x64EpU-nMQZH'
            b'iBeKeuavcGdRB24","a":[{"i":"ErLe2qWp4VCmDp7v_R01tC-ha13ZEZY0VGcg'
            b'YtPRhqPs","s":"0","d":"ESDuaqpoI8-HLD8-eLijUMZpXqYFkNArJFDvt3ABY'
            b'r9I"}]}-AABAAZ4V2cSIXYEPg5BtkJSHVBj-A0dGI6rH2XGaVt1kewqGeJjpy4uz'
            b'ObPWnoBpaEojFa5AnrUJEgMytORoWMqEhCw')

        # apply msg to bob's Kevery
        bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert bobK.serder.diger.qb64 == bobSrdr.dig  # key state updated so event was validated
        assert bobK.serder.diger.qb64 == 'EtzXPztLsGC5DGyooSdHdBGIOHjhblBWtZ_AOhGS-hDE'

        # apply msg to del's Kevery
        delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[bobPre].serder.diger.qb64 == bobSrdr.dig

        # now create msg with Del's delegated inception event
        sigers = delMgr.sign(ser=delSrdr.raw, verfers=verfers)

        msg = bytearray(delSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000165_","i":"ErLe2qWp4VCmDp7v_R01tC-ha13ZEZY0VG'
            b'cgYtPRhqPs","s":"0","t":"dip","kt":"1","k":["DuK1x8ydpucu3480Jpd'
            b'1XBfjnCwb3dZ3x5b1CJmuUphA"],"n":"EWWkjZkZDXF74O2bOQ4H5hu4nXDlKg2'
            b'm4CBEBkUxibiU","wt":"0","w":[],"c":[],"da":{"i":"EiBlVttjqvySMbA'
            b'4ShN19rSrz3D0ioNW-Uj92Ri7XnFE","s":"1","t":"ixn","p":"EvP2kWxEjT'
            b'MI3auc6x64EpU-nMQZHiBeKeuavcGdRB24"}}-AABAADv-a3LeXEStuY1LHknepu'
            b'J7mBcTByugqQ1TNRMrIa0rctfjKsh-hkkkpwDj6M_OLLaFtLqBpmdNTUgBPANLzCQ'
        )

        # apply Del's delegated inception event message to bob's Kevery
        bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert delPre in bobKvy.kevers  # successfully validated
        delK = bobKvy.kevers[delPre]
        assert delK.delegated
        assert delK.serder.diger.qb64 == delSrdr.dig  # key state updated so event was validated
        assert delK.serder.diger.qb64 == 'ESDuaqpoI8-HLD8-eLijUMZpXqYFkNArJFDvt3ABYr9I'

        # apply msg to del's Kevery
        delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[delPre].serder.diger.qb64 == delSrdr.dig

        # Setup Del rotation event assuming that Bob's next event will be an ixn delegating event
        verfers, digers, cst, nst = delMgr.rotate(pre=delPre, temp=True)

        seal = eventing.SealLocation(i=bobK.prefixer.qb64,
                                     s="{:x}".format(bobK.sn + 1),
                                     t=coring.Ilks.ixn,
                                     p=bobK.serder.diger.qb64)

        assert seal._asdict() == {
            'i': 'EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-Uj92Ri7XnFE',
            's': '2',
            't': 'ixn',
            'p': 'EtzXPztLsGC5DGyooSdHdBGIOHjhblBWtZ_AOhGS-hDE'
        }

        delSrdr = eventing.deltate(
            pre=delK.prefixer.qb64,
            keys=[verfer.qb64 for verfer in verfers],
            dig=delK.serder.diger.qb64,
            seal=seal,
            sn=delK.sn + 1,
            nxt=coring.Nexter(digs=[diger.qb64 for diger in digers]).qb64)

        assert delSrdr.dig == 'E-dZsWLp2IIPVDbGdGS-yvuw4HeV_w_w76FHsofmuiq0'

        # Now create delegating rotation event
        seal = eventing.SealEvent(i=delK.prefixer.qb64,
                                  s=delSrdr.ked["s"],
                                  d=delSrdr.dig)
        bobSrdr = eventing.interact(pre=bobK.prefixer.qb64,
                                    dig=bobK.serder.diger.qb64,
                                    sn=bobK.sn + 1,
                                    data=[seal._asdict()])

        sigers = bobMgr.sign(ser=bobSrdr.raw, verfers=bobK.verfers)

        msg = bytearray(bobSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON000107_","i":"EiBlVttjqvySMbA4ShN19rSrz3D0ioNW-U'
            b'j92Ri7XnFE","s":"2","t":"ixn","p":"EtzXPztLsGC5DGyooSdHdBGIOHjhb'
            b'lBWtZ_AOhGS-hDE","a":[{"i":"ErLe2qWp4VCmDp7v_R01tC-ha13ZEZY0VGcg'
            b'YtPRhqPs","s":"1","d":"E-dZsWLp2IIPVDbGdGS-yvuw4HeV_w_w76FHsofmu'
            b'iq0"}]}-AABAAmloDxOwz6ztvRR_4N8Hn-6ZJk6_0nQhfNE7bzX6NpJRfYDwmUw3'
            b'rXod0g46iFOLqEWw12oaFVzVH85NYAh67Ag')

        # apply msg to bob's Kevery
        bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert bobK.serder.diger.qb64 == bobSrdr.dig  # key state updated so event was validated

        # apply msg to del's Kevery
        delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[bobPre].serder.diger.qb64 == bobSrdr.dig

        # now create msg from Del's delegated rotation event
        sigers = delMgr.sign(ser=delSrdr.raw, verfers=verfers)

        msg = bytearray(delSrdr.raw)
        counter = coring.Counter(code=coring.CtrDex.ControllerIdxSigs,
                                 count=len(sigers))
        msg.extend(counter.qb64b)
        for siger in sigers:
            msg.extend(siger.qb64b)

        assert msg == bytearray(
            b'{"v":"KERI10JSON0001a1_","i":"ErLe2qWp4VCmDp7v_R01tC-ha13ZEZY0VG'
            b'cgYtPRhqPs","s":"1","t":"drt","p":"ESDuaqpoI8-HLD8-eLijUMZpXqYFk'
            b'NArJFDvt3ABYr9I","kt":"1","k":["DTf6QZWoet154o9wvzeMuNhLQRr8JaAU'
            b'eiC6wjB_4_08"],"n":"E8kyiXDfkE7idwWnAZQjHbUZMz-kd_yIMH0miptIFFPo'
            b'","wt":"0","wr":[],"wa":[],"a":[],"da":{"i":"EiBlVttjqvySMbA4ShN'
            b'19rSrz3D0ioNW-Uj92Ri7XnFE","s":"2","t":"ixn","p":"EtzXPztLsGC5DG'
            b'yooSdHdBGIOHjhblBWtZ_AOhGS-hDE"}}-AABAAXcUl6KlY4VOx8ZumFMc0uR4iH'
            b'BGmPQo4IAx0nIiiEDB_u2ewkvgIDIp1ELDGxfc2VVUkl38Z7PqwydBdpIK0DA')

        # apply Del's delegated inception event message to bob's Kevery
        bobKvy.process(ims=bytearray(msg))  # process local copy of msg
        assert delK.delegated
        assert delK.serder.diger.qb64 == delSrdr.dig  # key state updated so event was validated
        assert delK.serder.diger.qb64 == 'E-dZsWLp2IIPVDbGdGS-yvuw4HeV_w_w76FHsofmuiq0'

        # apply msg to del's Kevery
        delKvy.process(ims=bytearray(msg))  # process remote copy of msg
        assert delKvy.kevers[delPre].serder.diger.qb64 == delSrdr.dig

    assert not os.path.exists(delKS.path)
    assert not os.path.exists(delDB.path)
    assert not os.path.exists(bobKS.path)
    assert not os.path.exists(bobDB.path)
    """End Test"""
示例#19
0
def test_replay_all():
    """
    Test conjoint replay all

    Setup database with events from Deb, Cam, Bev, abd Art
    Replay all the events in database.

    """

    with basing.openDB(name="deb") as debDB, keeping.openKS(name="deb") as debKS, \
         basing.openDB(name="cam") as camDB, keeping.openKS(name="cam") as camKS, \
         basing.openDB(name="bev") as bevDB, keeping.openKS(name="bev") as bevKS, \
         basing.openDB(name="art") as artDB, keeping.openKS(name="art") as artKS:

        # setup Deb's habitat using default salt multisig already incepts
        sith = ["1/2", "1/2", "1/2"]  # weighted signing threshold
        debHab = habbing.Habitat(ks=debKS,
                                 db=debDB,
                                 isith=sith,
                                 icount=3,
                                 temp=True)
        assert debHab.ks == debKS
        assert debHab.db == debDB
        assert debHab.kever.prefixer.transferable

        # setup Cam's habitat using default salt multisig already incepts
        # Cam's receipts will be vrcs with 3 indexed sigantures attached
        sith = '2'  # hex str of threshold int
        camHab = habbing.Habitat(ks=camKS,
                                 db=camDB,
                                 isith=sith,
                                 icount=3,
                                 temp=True)
        assert camHab.ks == camKS
        assert camHab.db == camDB
        assert camHab.kever.prefixer.transferable

        # setup Bev's habitat using default salt nonstransferable already incepts
        # Bev's receipts will be rcts with a receipt couple attached
        sith = '1'  # hex str of threshold int
        bevHab = habbing.Habitat(ks=bevKS,
                                 db=bevDB,
                                 isith=sith,
                                 icount=1,
                                 transferable=False,
                                 temp=True)
        assert bevHab.ks == bevKS
        assert bevHab.db == bevDB
        assert not bevHab.kever.prefixer.transferable

        # setup Art's habitat using custom salt nonstransferable so not match Bev
        # already incepts
        # Art's receipts will be rcts with a receipt couple attached
        salt = coring.Salter(raw=b'abcdef0123456789').qb64
        sith = '1'  # hex str of threshold int
        artHab = habbing.Habitat(ks=artKS,
                                 db=artDB,
                                 isith=sith,
                                 icount=1,
                                 salt=salt,
                                 transferable=False,
                                 temp=True)
        assert artHab.ks == artKS
        assert artHab.db == artDB
        assert not artHab.kever.prefixer.transferable

        # Create series of event for Deb
        debMsgs = bytearray()
        debMsgs.extend(debHab.makeOwnInception())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.rotate())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())

        # Play debMsgs to Cam
        # create non-local kevery for Cam to process msgs from Deb
        camKevery = eventing.Kevery(db=camHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(debMsgs), kvy=camKevery)
        # camKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in camKevery.kevers
        assert camKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(camKevery.cues) == 7

        # get disjoints receipts (vrcs) from Cam of Deb's events by processing Cam's cues
        camMsgs = camHab.processCues(camKevery.cues)

        # Play camMsgs to Deb
        # create non-local kevery for Deb to process msgs from Cam
        debKevery = eventing.Kevery(db=debHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(camMsgs), kvy=debKevery)
        # debKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in debKevery.kevers
        assert debKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Cam's events by processing Deb's cues
        debCamVrcs = debHab.processCues(debKevery.cues)

        # Play disjoints debCamVrcs to Cam
        parsing.Parser().parseOne(ims=bytearray(debCamVrcs), kvy=camKevery)
        # camKevery.processOne(ims=bytearray(debCamVrcs))  # give copy to process

        # Play debMsgs to Bev
        # create non-local kevery for Bev to process msgs from Deb
        bevKevery = eventing.Kevery(db=bevHab.db, lax=False, local=False)
        parsing.Parser().parse(ims=bytearray(debMsgs), kvy=bevKevery)
        # bevKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in bevKevery.kevers
        assert bevKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(bevKevery.cues) == 7

        # get disjoints receipts (rcts) from Bev of Deb's events by processing Bevs's cues
        bevMsgs = bevHab.processCues(bevKevery.cues)

        # Play bevMsgs to Deb
        parsing.Parser().parse(ims=bytearray(bevMsgs), kvy=debKevery)
        # debKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in debKevery.kevers
        assert debKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Bev's events by processing Deb's cues
        debBevVrcs = debHab.processCues(debKevery.cues)

        # Play disjoints debBevVrcs to Bev
        parsing.Parser().parseOne(ims=bytearray(debBevVrcs), kvy=bevKevery)
        # bevKevery.processOne(ims=bytearray(debBevVrcs))  # give copy to process

        # now setup replay
        debAllFelMsgs = debHab.replayAll()
        assert len(debAllFelMsgs) == 11267

        # create non-local kevery for Art to process conjoint replay msgs from Deb
        artKevery = eventing.Kevery(db=artHab.db, lax=False, local=False)
        # process Cam's inception so Art will proces Cam's vrcs without escrowing
        camIcpMsg = camHab.makeOwnInception()
        parsing.Parser().parse(ims=bytearray(camIcpMsg), kvy=artKevery)
        assert camHab.pre in artKevery.kevers
        assert len(artKevery.cues) == 1
        # give copy to process in cloned mode
        artKevery.cloned = True
        parsing.Parser().parse(ims=bytearray(debAllFelMsgs), kvy=artKevery)
        assert debHab.pre in artKevery.kevers
        assert artKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(artKevery.cues) == 9
        artAllFelMsgs = artHab.replayAll()
        assert len(artAllFelMsgs) == 11016

    assert not os.path.exists(artKS.path)
    assert not os.path.exists(artDB.path)
    assert not os.path.exists(bevKS.path)
    assert not os.path.exists(bevDB.path)
    assert not os.path.exists(camKS.path)
    assert not os.path.exists(camDB.path)
    assert not os.path.exists(debKS.path)
    assert not os.path.exists(debDB.path)
    """End Test"""
示例#20
0
def test_replay():
    """
    Test disjoint and conjoint replay

    Deb creates series of events.
    Deb replays Deb's events to Cam and collects Cam's receipts
    Deb replays Deb's events with Cam's recepts to Bev and collects Bev's receipts
    Deb replays Deb's events with both Cam's and  Bev's receipts to Cam
    Compare replay of Deb's events with receipts by both Deb and Cam to confirm identical
    """

    with dbing.openDB(name="deb") as debDB, keeping.openKS(name="deb") as debKS, \
         dbing.openDB(name="cam") as camDB, keeping.openKS(name="cam") as camKS, \
         dbing.openDB(name="bev") as bevDB, keeping.openKS(name="bev") as bevKS, \
         dbing.openDB(name="art") as artDB, keeping.openKS(name="art") as artKS:

        # setup Deb's habitat using default salt multisig already incepts
        sith = ["1/2", "1/2", "1/2"]  # weighted signing threshold
        debHab = directing.Habitat(ks=debKS,
                                   db=debDB,
                                   isith=sith,
                                   icount=3,
                                   temp=True)
        assert debHab.ks == debKS
        assert debHab.db == debDB
        assert debHab.kever.prefixer.transferable

        # setup Cam's habitat using default salt multisig already incepts
        # Cam's receipts will be vrcs with 3 indexed sigantures attached
        sith = '2'  # hex str of threshold int
        camHab = directing.Habitat(ks=camKS,
                                   db=camDB,
                                   isith=sith,
                                   icount=3,
                                   temp=True)
        assert camHab.ks == camKS
        assert camHab.db == camDB
        assert camHab.kever.prefixer.transferable

        # setup Bev's habitat using default salt nonstransferable already incepts
        # Bev's receipts will be rcts with a receipt couple attached
        sith = '1'  # hex str of threshold int
        bevHab = directing.Habitat(ks=bevKS,
                                   db=bevDB,
                                   isith=sith,
                                   icount=1,
                                   transferable=False,
                                   temp=True)
        assert bevHab.ks == bevKS
        assert bevHab.db == bevDB
        assert not bevHab.kever.prefixer.transferable

        # setup Art's habitat using custom salt nonstransferable so not match Bev
        # already incepts
        # Art's receipts will be rcts with a receipt couple attached
        salt = coring.Salter(raw=b'abcdef0123456789').qb64
        sith = '1'  # hex str of threshold int
        artHab = directing.Habitat(ks=artKS,
                                   db=artDB,
                                   isith=sith,
                                   icount=1,
                                   salt=salt,
                                   transferable=False,
                                   temp=True)
        assert artHab.ks == artKS
        assert artHab.db == artDB
        assert not artHab.kever.prefixer.transferable

        # first setup disjoint replay then conjoint replay
        # Create series of event for Deb
        debMsgs = bytearray()
        debMsgs.extend(debHab.makeOwnInception())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.rotate())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())
        debMsgs.extend(debHab.interact())

        assert debMsgs == (
            b'{"v":"KERI10JSON00015b_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lry'
            b'kGGHz2vlMw","s":"0","t":"icp","kt":["1/2","1/2","1/2"],"k":["DaY'
            b'h8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg","Duzj-Z2lR2DqB0cI0421'
            b'oSMUVWOrN5axojx8g9fSx3PM","DRXPAmNVVqafWvQiN5qQmWUDvVupF2w8xFNGg'
            b'1Gays9Y"],"n":"EO5f_IQjtBoeN_-OyzfVJx1_WqBFUL-Ely4x-xmUtOW8","bt'
            b'":"0","b":[],"c":[],"a":[]}-AADAA1G77zOmX-GYRN5yk5X704dneyog8BHJ'
            b'ItCZdLmXl4Tlfd-bE3K8WpbApL_-n1o18Ato90tRhAIZjuBIlxF9vAgAByElIwoU'
            b'aqbuJzHevggmdBySCIropnrylNFmSETWjOwLT2ifZgCJ1lm27IbknR_33LPPIyN3'
            b'U6dbIAG3kko7IDgACdOTaaqRtwquJiBZJfWYKtH48gZTezMLzXviMUeo2Z1cJ-_M'
            b'xQvDNh85FjXAOEQ-3hPEiqmY1SpjElZIXGs13DA{"v":"KERI10JSON000098_",'
            b'"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"1","t":"'
            b'ixn","p":"E5OQH-DOSjcX8JlBtznPaaawhP0iuZhjf9cxWVAXNTX0","a":[]}-'
            b'AADAAO7JjY0oHH5z68S4ZlYUAOAFnMfRu6OZB9hMGgu6teSzvL_3kzAiiPig6vch'
            b'lnXDxmKFWMDLXAZsCBN3T0chVCwAB_I3BVOYI2K_VSeLDcq32czYe-kTyPZ1E0wd'
            b'-F78Ixsz99mQwwylJsbRBb2l1Q2-1UnbQ4NZzj0w2xo5fEBv4BAACHO5PyuMrekU'
            b'FWbirPNt7etpA3cUVAR94XFlJDUYYSE4tq1gD6Pab-L2PP3ifFlluO-aoVpf3G8h'
            b'Sl75t2k7rCg{"v":"KERI10JSON000190_","i":"EBfdpo5wnI3XTcdUIgJRf1-'
            b'xLhy8Ud8lrykGGHz2vlMw","s":"2","t":"rot","p":"EjevD0KmiBZQHqVNND'
            b'mpTfrp0lqZI5eicRRNf3OqLW9o","kt":["1/2","1/2","1/2"],"k":["DIsi8'
            b'qYso1KMmpLOGYty3NC2BAojZmUCfzR5_5oQRiso","DkdClpaWCAoCPBYgUmqP9g'
            b'wAtsGq81yyPhGQKQ6-W_F0","DKDyq4QQYKnx9ircxeCvEcraI4HUSr_ytWPelDH'
            b'AM98w"],"n":"E1oOvJmwenmC4uHjX7qB40LGVbeZY5rYQeZ6IK5zmdmM","bt":'
            b'"0","br":[],"ba":[],"a":[]}-AADAAfELYptGBeOzZ1ex7MIxYAUN_f4mr0gZ'
            b'gUZAQTZQbZKsTykDGqTcsbuLurhFviHttWylHBBjDwfCRF8eFCpLkDgABRLbYyJQ'
            b'W8plPZ3PcdBLHgl4NWnB5NeTOI9tjW53DL4le2N-nVPVXr_fAvWcksevbGNRZxCU'
            b'ePoDlThcBShDdBwACSPQd27SozRqfeW7YWWQS87JXdgy-ZGTrhrT1bUTTQKAngwE'
            b'1hwWgIYw8LUgz3YH6SZC5zAWUN_Fv3OzSb_BXBg{"v":"KERI10JSON000098_",'
            b'"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"3","t":"'
            b'ixn","p":"Ew3t8tlmqfRSwyyRF1nsKLjNOySvj-KTd-SmDu_AjzuA","a":[]}-'
            b'AADAAJ4MM4lGyFUsszt7fXksb13wqyiBTd3AirhQaTO3udtTilMfviCutx-ipkgT'
            b'u56huDbWLiA47LqUzqP63rKv3DQAB9hmDtEawFFGHMeS92RBuuMMQroBM5fodzeo'
            b'leSrV0IyETDSpjaRhcsDf25EqNTJUcnv-_jSzRPEtM8GEv3AJCgACxWtyOC4ks1F'
            b'8-YdHSM32VLysW0ypRBpfYDOHyfmtktb1XQjdAAJpkSDe9wvrttvE2xJ5GzyfpVv'
            b'Ps4zK54pCDA{"v":"KERI10JSON000098_","i":"EBfdpo5wnI3XTcdUIgJRf1-'
            b'xLhy8Ud8lrykGGHz2vlMw","s":"4","t":"ixn","p":"EY_w2vUVqsE6jdgdxJ'
            b'VvMW3434NG1w_asCW7ohG1nmMY","a":[]}-AADAANw16XHQyB4Edm0MF4b0m8Ez'
            b'8jOZSYr_bYn7ilsFTNBypC_tSIcLnOUarG1xuhFU21WjXiSHWt2t2BSIHulgtDgA'
            b'Bm1DN8JigUofEC8mXb7YgklycIqDt7F7p8s6x8VHlAqLsCiMsXGQlRCwUwF7DFeu'
            b'6Fw_43Io6evqKpzaTR31SCwACJE0jOjykDr4SU59Mpd-EBTwKc8hUUWeIQTF3qU4'
            b'H56jqKozmgsyzzViob_DZ828OGBLRG_WoIQxTvstXql3QDw{"v":"KERI10JSON0'
            b'00098_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"'
            b'5","t":"ixn","p":"EwJ79SUIE69dA0my9ai9hK3yH8cqqyD9CS62lyRTDn-o",'
            b'"a":[]}-AADAAhAypLrhzTbvSPdErva4IzRRSq6EZCC_dCe3pkLGpPcVHdi3Mu2B'
            b'-c0oW1My7HFFa1-JNTbjnNtgK-Or297PmAgABM1DYwa0Khbr79SbRaC6l8rAwsxs'
            b'Vopeid8KfS-7pt60y9drfLpXIUFzt5rk24KUuZROO33KiHmfKNbviW6GVCgACQRj'
            b'qwHlELgvpFJwQx-6yBVuAgbsT7AK1mbxfsUo2XfzkAUTbn9H1vxOQX1Rg_3cLYZv'
            b'ryKcP4MdjZFfFYaNmBQ{"v":"KERI10JSON000098_","i":"EBfdpo5wnI3XTcd'
            b'UIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"6","t":"ixn","p":"EBjW8_7rqn'
            b'AXV0Il5BJ4XWZcIb355Ltj-9F9JRZLn75c","a":[]}-AADAAbbH94e474Pflg_Y'
            b'dlivHMQQL_7rUlr1DEut8SSbEs6cmUixWHW8SuZG2UlpKoqsAL-STNALsRCmDw_2'
            b'wWsmWAAABnedMdYxUbNgwJpG5AcNsxMIZCjuu486-wuiUm3BO_1h40_qvoMicneV'
            b'edtBOLxD5zKtdZhBHZqtd3-qQDmIVDgACqms_mYs0LAwAi2zGN6lpKmdqs2twyJz'
            b'9xiyPeERHG7D2FiTZqow19UieVYobmhGeHuoS5WxNPgcponbhHeFnDA')

        # Play debMsgs to Cam
        # create non-local kevery for Cam to process msgs from Deb
        camKevery = eventing.Kevery(kevers=camHab.kevers,
                                    db=camHab.db,
                                    framed=True,
                                    opre=camHab.pre,
                                    local=False)
        camKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in camKevery.kevers
        assert camKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(camKevery.cues) == 7

        # get disjoints receipts (vrcs) from Cam of Deb's events by processing Cam's cues
        camMsgs = camHab.processCues(camKevery.cues)
        assert camMsgs == (
            b'{"v":"KERI10JSON00014b_","i":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP'
            b'6GfapWi5MU","s":"0","t":"icp","kt":"2","k":["DaYh8uaASuDjMUd8_Bo'
            b'NyQs3GwupzmJL8_RBsuNtZHQg","Duzj-Z2lR2DqB0cI0421oSMUVWOrN5axojx8'
            b'g9fSx3PM","DRXPAmNVVqafWvQiN5qQmWUDvVupF2w8xFNGg1Gays9Y"],"n":"E'
            b'OySO3Oa400n3Ss9JftGYmgS5M4jgPInNnMntC_l-PEQ","bt":"0","b":[],"c"'
            b':[],"a":[]}-AADAATacW---OhatYudCOUeNdVpYq8Vk_LIKMQML86xz4b1ZQG9r'
            b'ahEGEHMtDacANGyKFSkJBq4F3x8h30lWfrth2BQABnyZMjYDQs2IgFuVcRKCLi9F'
            b'DFOw7uPqIvwossbC4H2Eu4_cIntaKeEmH7LBEzDbfQaQxWdgZ2YTnfFkoznL3AgA'
            b'Ckf4d23ErgdwPZWJf_0jVtzVwoKsh_6W0V6BclmrbnL1NWM8ox2m3ff7LzZeSjF5'
            b'9AvO-QmqCD325H3igOF0HCg{"v":"KERI10JSON000105_","i":"EBfdpo5wnI3'
            b'XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"0","t":"vrc","d":"E5OQH-'
            b'DOSjcX8JlBtznPaaawhP0iuZhjf9cxWVAXNTX0","a":{"i":"EiRjCnZfca8gUZ'
            b'qecerjGpjkiY8dIkGudP6GfapWi5MU","s":"0","d":"E1tSV5RBIG7dGPN2Oof'
            b'5DmZCqgGgpF7P9BbfOTnOEEpM"}}-AADAA1G77zOmX-GYRN5yk5X704dneyog8BH'
            b'JItCZdLmXl4Tlfd-bE3K8WpbApL_-n1o18Ato90tRhAIZjuBIlxF9vAgAByElIwo'
            b'UaqbuJzHevggmdBySCIropnrylNFmSETWjOwLT2ifZgCJ1lm27IbknR_33LPPIyN'
            b'3U6dbIAG3kko7IDgACdOTaaqRtwquJiBZJfWYKtH48gZTezMLzXviMUeo2Z1cJ-_'
            b'MxQvDNh85FjXAOEQ-3hPEiqmY1SpjElZIXGs13DA{"v":"KERI10JSON000105_"'
            b',"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"1","t":'
            b'"vrc","d":"EjevD0KmiBZQHqVNNDmpTfrp0lqZI5eicRRNf3OqLW9o","a":{"i'
            b'":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP6GfapWi5MU","s":"0","d":"E1'
            b'tSV5RBIG7dGPN2Oof5DmZCqgGgpF7P9BbfOTnOEEpM"}}-AADAAO7JjY0oHH5z68'
            b'S4ZlYUAOAFnMfRu6OZB9hMGgu6teSzvL_3kzAiiPig6vchlnXDxmKFWMDLXAZsCB'
            b'N3T0chVCwAB_I3BVOYI2K_VSeLDcq32czYe-kTyPZ1E0wd-F78Ixsz99mQwwylJs'
            b'bRBb2l1Q2-1UnbQ4NZzj0w2xo5fEBv4BAACHO5PyuMrekUFWbirPNt7etpA3cUVA'
            b'R94XFlJDUYYSE4tq1gD6Pab-L2PP3ifFlluO-aoVpf3G8hSl75t2k7rCg{"v":"K'
            b'ERI10JSON000105_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2v'
            b'lMw","s":"2","t":"vrc","d":"Ew3t8tlmqfRSwyyRF1nsKLjNOySvj-KTd-Sm'
            b'Du_AjzuA","a":{"i":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP6GfapWi5MU'
            b'","s":"0","d":"E1tSV5RBIG7dGPN2Oof5DmZCqgGgpF7P9BbfOTnOEEpM"}}-A'
            b'ADAABkB5LzkcturaQSzTGH_KrWsEJR-x_CH8UPl9FQ1Dc461z5-Fdn3TLJ7DpUw-'
            b'6VrbKGGjuDy2Nkg0xJdzh4F8CQABPgHmWCG4uUicqcBiHOJcygFsSqFMU2jkOgU7'
            b'3eG-Jony_ZwctQl_1BCQ8eVTli44Uou4YMdgvRMfmiRGTuxeAwAC386oYzhQFZCk'
            b'S6TM9vIFahT8vf0cQ7t2v5MqKhyJxBgA6CHJeQ8mxS8P7trjcEOGl79jwb6L-jyt'
            b'qAnNPDJFCA{"v":"KERI10JSON000105_","i":"EBfdpo5wnI3XTcdUIgJRf1-x'
            b'Lhy8Ud8lrykGGHz2vlMw","s":"3","t":"vrc","d":"EY_w2vUVqsE6jdgdxJV'
            b'vMW3434NG1w_asCW7ohG1nmMY","a":{"i":"EiRjCnZfca8gUZqecerjGpjkiY8'
            b'dIkGudP6GfapWi5MU","s":"0","d":"E1tSV5RBIG7dGPN2Oof5DmZCqgGgpF7P'
            b'9BbfOTnOEEpM"}}-AADAAraP5JCHU-ZQwsDAWuLu_fvvYmkpVEu071l5P7fwHzqL'
            b'bJ7kkvpSsXcGs2HpW_Bw_fjp07LfnN4de5zn7-owxAgABQUHJIy3inow-7ctn-jO'
            b'F6r2IvOsC-Pl2jAueDZfH9p2pS_L9OhgHBr9ToilY4H_1bbIZK2kERtt47Qd0VVq'
            b'qDAAC_0A73HjuuB42XhAqgPMWt1Fm-FwO55oT0z7TJR9PQ4ppaEuip5FUp-miRS9'
            b'Rnoq0ZYPWskncUmLgcqxsOksvBw{"v":"KERI10JSON000105_","i":"EBfdpo5'
            b'wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"4","t":"vrc","d":"Ew'
            b'J79SUIE69dA0my9ai9hK3yH8cqqyD9CS62lyRTDn-o","a":{"i":"EiRjCnZfca'
            b'8gUZqecerjGpjkiY8dIkGudP6GfapWi5MU","s":"0","d":"E1tSV5RBIG7dGPN'
            b'2Oof5DmZCqgGgpF7P9BbfOTnOEEpM"}}-AADAApIX866iuD6j14MFQbVdiJHMeTM'
            b'Svd2EoibE7PPfwU7f6HcDCwmLmMCNpRVwM-Kf1kKIor7TETSX80jrliA_XBgAB1h'
            b'phj5XH3E0oTANv6GVwJ5s0ZnLIPSYoBuvXaPOzWgW3nynVPwWnqCNuP7rdh-1NVB'
            b'QUc9QHqrDWVnJaoVo5CQAC9PBjGWWN9J6jQXcLmQOfQxrWL3NFm93r7-nDiSbG-T'
            b'KDvbcXcnoLfCitTt_B96JlvIpe6cI8DJZw3_SERLsaCg{"v":"KERI10JSON0001'
            b'05_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"5",'
            b'"t":"vrc","d":"EBjW8_7rqnAXV0Il5BJ4XWZcIb355Ltj-9F9JRZLn75c","a"'
            b':{"i":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP6GfapWi5MU","s":"0","d"'
            b':"E1tSV5RBIG7dGPN2Oof5DmZCqgGgpF7P9BbfOTnOEEpM"}}-AADAApBHqjI7V9'
            b'yrCqUP1ZsnSHov3nNF90QNZEwPGZToAf6l3KeXPh4UQMZU70-5Cbbs2mswX8_Tg4'
            b'5orHQz_mQkMCgABF3FoOib-wh0KQ26kdzfEBtnenPVN12GiP7NpIy2j3wW-enfJc'
            b'gRTEE3XWVekl3IkU3o70Cnk4K1PONYCrO6hAwACWMhg7tNGae9I4mLtv5rVpb9Rr'
            b'G70zGIwBDxN4QahABHlAvRdDpaSE5BpJ7nlOkShOZIva-qdcWS5TiRX8I43DQ{"v'
            b'":"KERI10JSON000105_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGG'
            b'Hz2vlMw","s":"6","t":"vrc","d":"E8BEZ7sVSL-vamQnB8Oc72ov-gpiXJzL'
            b'GXeiAW9_Vht8","a":{"i":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP6GfapW'
            b'i5MU","s":"0","d":"E1tSV5RBIG7dGPN2Oof5DmZCqgGgpF7P9BbfOTnOEEpM"'
            b'}}-AADAAlQ8kt9KwijVTzAS8-LUziqMPwvLDhoU9sVHN0a9wkICnezEmzrb4skeO'
            b'wdNVbpek3Wn6xcRxa5wCuF9ub3T-CAAByaYGW-0ZX6oDmjk70BOpkRl8JvgVCm9w'
            b'skxESXXFcMs_FWssXcUH1oDRzA2q7BMW80DpEtKtcY8phmbH8TTBBwACQd7bqYf-'
            b'hcHe2B_FESYMXH2SloJ1o7XOry4KyBxZ9oJwtoa0iR4JPScb4_ix1p8p9n3HGMXT'
            b'_Lou1q1l6AGAAQ')

        # Play camMsgs to Deb
        # create non-local kevery for Deb to process msgs from Cam
        debKevery = eventing.Kevery(kevers=debHab.kevers,
                                    db=debHab.db,
                                    framed=True,
                                    opre=debHab.pre,
                                    local=False)
        debKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in debKevery.kevers
        assert debKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Cam's events by processing Deb's cues
        debCamVrcs = debHab.processCues(debKevery.cues)
        assert debCamVrcs == (
            b'{"v":"KERI10JSON000105_","i":"EiRjCnZfca8gUZqecerjGpjkiY8dIkGudP'
            b'6GfapWi5MU","s":"0","t":"vrc","d":"E1tSV5RBIG7dGPN2Oof5DmZCqgGgp'
            b'F7P9BbfOTnOEEpM","a":{"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGG'
            b'Hz2vlMw","s":"2","d":"Ew3t8tlmqfRSwyyRF1nsKLjNOySvj-KTd-SmDu_Ajz'
            b'uA"}}-AADAAII8AatcRUlekxpknQfnpZJ2KBrATxmFRLxb_zpdPOaG3pCQg6vqP0'
            b'G96WmJO0hFwaGL-xheGy-SvX_5Q8b0gDQABRgVbtBmb3lR7UjuBjHmny7QkJ6waR'
            b'MTwz2B_1ANJu9yDa5qsgJiMQ7aTc7lCpLJgZNyKUJaUmW8YJL6JrzteDwAC1zKj3'
            b'HCcHwhw7OtEVXrgIobJO27d6389xdPXpkdVENb6XbsQLDEPNtv3g2POvWx1vESlp'
            b'pIfOxaY8VATudBBBg')

        # Play disjoints debCamVrcs to Cam
        camKevery.processOne(ims=bytearray(debCamVrcs))  # give copy to process

        # Play debMsgs to Bev
        # create non-local kevery for Bev to process msgs from Deb
        bevKevery = eventing.Kevery(kevers=bevHab.kevers,
                                    db=bevHab.db,
                                    framed=True,
                                    opre=bevHab.pre,
                                    local=False)
        bevKevery.process(ims=bytearray(debMsgs))  # give copy to process
        assert debHab.pre in bevKevery.kevers
        assert bevKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(bevKevery.cues) == 7

        # get disjoints receipts (rcts) from Bev of Deb's events by processing Bevs's cues
        bevMsgs = bevHab.processCues(bevKevery.cues)
        assert bevMsgs == (
            b'{"v":"KERI10JSON0000c1_","i":"BaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_'
            b'RBsuNtZHQg","s":"0","t":"icp","kt":"1","k":["BaYh8uaASuDjMUd8_Bo'
            b'NyQs3GwupzmJL8_RBsuNtZHQg"],"n":"","bt":"0","b":[],"c":[],"a":[]'
            b'}-AABAA8dCt6i3swKOHoV10pEEOT7LOHxDWCfPWJm0Qvf6CXNaxTEOthHVgLihIz'
            b'1ZwQYc_nvunt0Hkh5TnnG4OmnulCQ{"v":"KERI10JSON000091_","i":"EBfdp'
            b'o5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"0","t":"rct","d":"'
            b'E5OQH-DOSjcX8JlBtznPaaawhP0iuZhjf9cxWVAXNTX0"}-CABBaYh8uaASuDjMU'
            b'd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0B1G77zOmX-GYRN5yk5X704dneyog8BHJI'
            b'tCZdLmXl4Tlfd-bE3K8WpbApL_-n1o18Ato90tRhAIZjuBIlxF9vAg{"v":"KERI'
            b'10JSON000091_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw'
            b'","s":"1","t":"rct","d":"EjevD0KmiBZQHqVNNDmpTfrp0lqZI5eicRRNf3O'
            b'qLW9o"}-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0BO7JjY0o'
            b'HH5z68S4ZlYUAOAFnMfRu6OZB9hMGgu6teSzvL_3kzAiiPig6vchlnXDxmKFWMDL'
            b'XAZsCBN3T0chVCw{"v":"KERI10JSON000091_","i":"EBfdpo5wnI3XTcdUIgJ'
            b'Rf1-xLhy8Ud8lrykGGHz2vlMw","s":"2","t":"rct","d":"Ew3t8tlmqfRSwy'
            b'yRF1nsKLjNOySvj-KTd-SmDu_AjzuA"}-CABBaYh8uaASuDjMUd8_BoNyQs3Gwup'
            b'zmJL8_RBsuNtZHQg0BBkB5LzkcturaQSzTGH_KrWsEJR-x_CH8UPl9FQ1Dc461z5'
            b'-Fdn3TLJ7DpUw-6VrbKGGjuDy2Nkg0xJdzh4F8CQ{"v":"KERI10JSON000091_"'
            b',"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"3","t":'
            b'"rct","d":"EY_w2vUVqsE6jdgdxJVvMW3434NG1w_asCW7ohG1nmMY"}-CABBaY'
            b'h8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0BraP5JCHU-ZQwsDAWuLu_f'
            b'vvYmkpVEu071l5P7fwHzqLbJ7kkvpSsXcGs2HpW_Bw_fjp07LfnN4de5zn7-owxA'
            b'g{"v":"KERI10JSON000091_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lr'
            b'ykGGHz2vlMw","s":"4","t":"rct","d":"EwJ79SUIE69dA0my9ai9hK3yH8cq'
            b'qyD9CS62lyRTDn-o"}-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZH'
            b'Qg0BpIX866iuD6j14MFQbVdiJHMeTMSvd2EoibE7PPfwU7f6HcDCwmLmMCNpRVwM'
            b'-Kf1kKIor7TETSX80jrliA_XBg{"v":"KERI10JSON000091_","i":"EBfdpo5w'
            b'nI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","s":"5","t":"rct","d":"EBj'
            b'W8_7rqnAXV0Il5BJ4XWZcIb355Ltj-9F9JRZLn75c"}-CABBaYh8uaASuDjMUd8_'
            b'BoNyQs3GwupzmJL8_RBsuNtZHQg0BpBHqjI7V9yrCqUP1ZsnSHov3nNF90QNZEwP'
            b'GZToAf6l3KeXPh4UQMZU70-5Cbbs2mswX8_Tg45orHQz_mQkMCg{"v":"KERI10J'
            b'SON000091_","i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGGHz2vlMw","'
            b's":"6","t":"rct","d":"E8BEZ7sVSL-vamQnB8Oc72ov-gpiXJzLGXeiAW9_Vh'
            b't8"}-CABBaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_RBsuNtZHQg0BlQ8kt9Kwij'
            b'VTzAS8-LUziqMPwvLDhoU9sVHN0a9wkICnezEmzrb4skeOwdNVbpek3Wn6xcRxa5'
            b'wCuF9ub3T-CA')

        # Play bevMsgs to Deb
        debKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in debKevery.kevers
        assert debKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(debKevery.cues) == 1

        # get disjoints receipts (vrcs) from Deb of Bev's events by processing Deb's cues
        debBevVrcs = debHab.processCues(debKevery.cues)
        assert debBevVrcs == (
            b'{"v":"KERI10JSON000105_","i":"BaYh8uaASuDjMUd8_BoNyQs3GwupzmJL8_'
            b'RBsuNtZHQg","s":"0","t":"vrc","d":"EW4yC5ZUXv8xhM3gXDvKwOCZkltCh'
            b'RZe-hTb2mi1Zf04","a":{"i":"EBfdpo5wnI3XTcdUIgJRf1-xLhy8Ud8lrykGG'
            b'Hz2vlMw","s":"2","d":"Ew3t8tlmqfRSwyyRF1nsKLjNOySvj-KTd-SmDu_Ajz'
            b'uA"}}-AADAAmQ-kOahYYNCaatYN5YHfuruD93tOhJNQCt7Wy6LUCCkITxSj7Ogux'
            b'aDrBo15FN7wk-BTgEV8ufOIsxhqVfmVBgAB5DhNTiOesOQxfxSn-0D7Ec9_S80xO'
            b'9ck6Q6FKROXz2Evd4_TwfzMbgJKjSPXqkA16zju5GN6aDWeGWCJOTceDwACrkW_1'
            b'_sKmtEWtlcON3IGzRygPc0tF-f5qTRJewOEIRIhCB81WnDi8PBa7F43YzSoJiSGV'
            b'_PgAcg6zh6q8wxVDQ')

        # Play disjoints debBevVrcs to Bev
        bevKevery.processOne(ims=bytearray(debBevVrcs))  # give copy to process

        # now setup conjoint replay

        # Replay Deb's First Seen Events with receipts (vrcs and rcts) from both Cam and Bev
        # datetime is different in each run in the fse attachment in clone replay
        # so we either have to force dts in db or we parse in pieces
        debFelMsgs = bytearray()
        fn = 0
        cloner = debHab.db.cloneIter(pre=debHab.pre, fn=fn)  # create iterator
        msg = next(cloner)  # get zeroth event with attachments
        assert len(msg) == 1423
        debFelMsgs.extend(msg)

        # parse msg
        serder = coring.Serder(raw=msg)
        assert serder.raw == debHab.iserder.raw
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.icp
        del msg[:len(serder.raw)]
        assert len(msg) == 1076

        counter = coring.Counter(
            qb64b=msg)  # attachment length quadlets counter
        assert counter.code == coring.CtrDex.AttachedMaterialQuadlets
        assert counter.count == (len(msg) - len(counter.qb64b)) // 4 == 268
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1072 == 268 * 4

        counter = coring.Counter(qb64b=msg)  # indexed signatures counter
        assert counter.code == coring.CtrDex.ControllerIdxSigs
        assert counter.count == 3  #  multisig deb
        del msg[:len(counter.qb64b)]
        assert len(msg) == 1068

        for i in range(counter.count):  # parse signatures
            siger = coring.Siger(qb64b=msg)
            del msg[:len(siger.qb64b)]
        assert len(msg) == 1068 - 3 * len(siger.qb64b) == 804

        counter = coring.Counter(qb64b=msg)  # trans receipt (vrc) counter
        assert counter.code == coring.CtrDex.TransReceiptQuadruples
        assert counter.count == 3  #  multisig cam
        del msg[:len(counter.qb64b)]
        assert len(msg) == 800

        for i in range(counter.count):  # parse receipt quadruples
            prefixer, seqner, diger, siger = eventing.deTransReceiptQuadruple(
                msg, strip=True)
        assert len(msg) == 800 - 3 * (len(prefixer.qb64b) + len(
            seqner.qb64b) + len(diger.qb64b) + len(siger.qb64b)) == 200

        counter = coring.Counter(qb64b=msg)  # nontrans receipt (rct) counter
        assert counter.code == coring.CtrDex.NonTransReceiptCouples
        assert counter.count == 1  #  single sig bev
        del msg[:len(counter.qb64b)]
        assert len(msg) == 196

        for i in range(counter.count):  # parse receipt couples
            prefixer, cigar = eventing.deReceiptCouple(msg, strip=True)
        assert len(
            msg) == 196 - 1 * (len(prefixer.qb64b) + len(cigar.qb64b)) == 64

        counter = coring.Counter(qb64b=msg)  # first seen replay couple counter
        assert counter.code == coring.CtrDex.FirstSeenReplayCouples
        assert counter.count == 1
        del msg[:len(counter.qb64b)]
        assert len(msg) == 60

        seqner = coring.Seqner(qb64b=msg)
        assert seqner.sn == fn == 0
        del msg[:len(seqner.qb64b)]
        assert len(msg) == 36  # 24 less

        dater = coring.Dater(qb64b=msg)
        assert (helping.fromIso8601(helping.nowIso8601()) -
                helping.fromIso8601(dater.dts)) > datetime.timedelta()
        del msg[:len(dater.qb64b)]
        assert len(msg) == 0  # 36 less

        cloner.close()  # must close or get lmdb error upon with exit
        """Exception ignored in: <generator object LMDBer.getAllOrdItemPreIter at 0x106fe1c10>
        Traceback (most recent call last):
        File "/Users/Load/Data/Code/public/keripy/src/keri/db/dbing.py", line 512, in getAllOrdItemPreIter
        yield (cn, bytes(val))  # (on, dig) of event
        lmdb.Error: Attempt to operate on closed/deleted/dropped object.
        """

        fn += 1
        cloner = debHab.db.cloneIter(pre=debHab.pre,
                                     fn=fn)  # create iterator not at 0
        msg = next(cloner)  # next event with attachments
        assert len(msg) == 1228
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.ixn
        debFelMsgs.extend(msg)

        fn += 1
        msg = next(cloner)  # get zeroth event with attachments
        serder = coring.Serder(raw=msg)
        assert serder.sn == fn  # no recovery forks so sn == fn
        assert serder.ked["t"] == coring.Ilks.rot
        assert len(msg) == 1476
        assert ([verfer.qb64 for verfer in serder.verfers
                 ] == [verfer.qb64 for verfer in debHab.kever.verfers])
        debFelMsgs.extend(msg)

        fn += 1
        while (fn <= 6):
            msg = next(cloner)  # get zeroth event with attachments
            serder = coring.Serder(raw=msg)
            assert serder.sn == fn  # no recovery forks so sn == fn
            assert serder.ked["t"] == coring.Ilks.ixn
            assert len(msg) == 1228
            debFelMsgs.extend(msg)
            fn += 1

        assert len(debFelMsgs) == 9039
        cloner.close()  # must close or get lmdb error upon with exit

        msgs = debHab.replay()
        assert msgs == debFelMsgs

        # Play Cam's messages to Bev
        bevKevery.process(ims=bytearray(camMsgs))  # give copy to process
        assert camHab.pre in bevKevery.kevers
        assert bevKevery.kevers[camHab.pre].sn == camHab.kever.sn == 0
        assert len(bevKevery.cues) == 1

        # Play Bev's messages to Cam
        camKevery.process(ims=bytearray(bevMsgs))  # give copy to process
        assert bevHab.pre in camKevery.kevers
        assert camKevery.kevers[bevHab.pre].sn == bevHab.kever.sn == 0
        assert len(camKevery.cues) == 1

        camDebFelMsgs = camHab.replay(pre=debHab.pre)
        bevDebFelMsgs = bevHab.replay(pre=debHab.pre)

        assert len(bevDebFelMsgs) == len(camDebFelMsgs) == len(
            debFelMsgs) == 9039

        # create non-local kevery for Art to process conjoint replay msgs from Deb
        artKevery = eventing.Kevery(kevers=artHab.kevers,
                                    db=artHab.db,
                                    framed=True,
                                    opre=artHab.pre,
                                    local=False)
        # process Cam's inception so Art will proces Cam's vrcs without escrowing
        camIcpMsg = camHab.makeOwnInception()
        artKevery.process(ims=bytearray(camIcpMsg))
        assert camHab.pre in artKevery.kevers
        assert len(artKevery.cues) == 1

        artKevery.process(ims=bytearray(debFelMsgs),
                          cloned=True)  # give copy to process
        assert debHab.pre in artKevery.kevers
        assert artKevery.kevers[debHab.pre].sn == debHab.kever.sn == 6
        assert len(artKevery.cues) == 8
        artDebFelMsgs = artHab.replay(pre=debHab.pre)
        assert len(artDebFelMsgs) == 9039

    assert not os.path.exists(artKS.path)
    assert not os.path.exists(artDB.path)
    assert not os.path.exists(bevKS.path)
    assert not os.path.exists(bevDB.path)
    assert not os.path.exists(camKS.path)
    assert not os.path.exists(camDB.path)
    assert not os.path.exists(debKS.path)
    assert not os.path.exists(debDB.path)
    """End Test"""