def backer_revoke( vcdig, regk, regsn, regd, version=Version, kind=Serials.json, ): """ Returns serder of brv message event Utility function to create a VC revocation event Parameters: vcdig is hash digest of vc content qb64 regk is regsitry identifier prefix qb64 regsn is int sequence number of anchoring registry TEL event regd is digest qb64 of anchoring registry TEL event """ vs = Versify(version=version, kind=kind, size=0) isn = 1 ilk = Ilks.rev seal = SealEvent(regk, regsn, regd) ked = dict( v=vs, i=vcdig, s="{:x}".format(isn), # hex string no leading zeros lowercase t=ilk, ra=seal._asdict()) return Serder(ked=ked) # return serialized ked
def __init__(self, hab, name="test", reg=None, allowBackers=True, baks=None, toad=None, estOnly=False): """ Initialize Instance Parameters: name is the alias for this issuer hab is Habitat instance of local controller's context reg is Registry instance for controller's credentials allowBackers is boolean True to allow specification of TEL specific backers backers is the initial list of backer prefixes qb64 for VCs in the Registry toad is int or str hex of witness threshold estOnly is boolean True for forcing rotation events for every TEL event. """ self.estOnly = estOnly self.allowBackers = allowBackers self.hab = hab self.name = name self.regi = 0 self.vcser = None self.reg = reg if reg is not None else Registry(name=name) # save backers locally for now. will be managed by tever when implemented self.backers = baks if baks is not None else [] self.cnfg = [] if self.allowBackers else [TraitDex.NoBackers] self.regser = eventing.incept(self.hab.pre, baks=self.backers, toad=toad, cnfg=self.cnfg, code=MtrDex.Blake3_256) self.regk = self.regser.pre rseal = SealEvent(self.regk, self.regser.ked["s"], self.regser.diger.qb64) if self.estOnly: self.ianchor = self.hab.rotate(data=rseal) else: self.ianchor = self.hab.interact(data=rseal) seal = SealEvent(i=self.hab.pre, s=self.hab.kever.sn, d=self.hab.kever.serder.dig) msg = self.messagize(serder=self.regser, seal=seal) # Process message in local Tevery when ready for now assign to self for testing self.incept = msg
def rotate(self, toad=None, cuts=None, adds=None): """ Rotate backer list for registry Parameters: toad is int or str hex of backer threshold after cuts and adds cuts is list of qb64 pre of backers to be removed from witness list adds is list of qb64 pre of backers to be added to witness list """ if not self.allowBackers: raise ValueError("Attempt to rotate registry {} that does not support backers".format(self.regk)) serder = eventing.rotate(dig=self.regser.dig, regk=self.regk, sn=self.regi+1, toad=toad, baks=self.backers, adds=adds, cuts=cuts) self.regser = serder rseal = SealEvent(self.regk, serder.ked["s"], self.regser.diger.qb64) tevt, kevt = self.anchorMsg(serder, rseal) # Process message in local Tevery when ready self.regi += 1 return tevt, kevt
def anchorMsg(self, serder, rseal): if self.estOnly: kevt = self.hab.rotate(data=rseal) else: kevt = self.hab.interact(data=rseal) seal = SealEvent(i=self.hab.pre, s=self.hab.kever.sn, d=self.hab.kever.serder.dig) tevt = self.messagize(serder=serder, seal=seal) return tevt, kevt
def issue(self, vcdig): """ Create and process an iss or bis message event Parameters: vcdig is hash digest of vc content qb64 """ if self.allowBackers: serder = eventing.backer_issue(vcdig=vcdig, regk=self.regk, regsn=self.regi, regd=self.regser.diger.qb64) else: serder = eventing.issue(vcdig=vcdig, regk=self.regk) self.vcser = serder rseal = SealEvent(vcdig, self.vcser.ked["s"], self.vcser.diger.qb64) msg, kevt = self.anchorMsg(serder, rseal) # Process message in local Tevery when ready return msg, kevt
def test_direct_mode_with_manager(): """ Test direct mode with transferable validator event receipts """ # manual process to generate a list of secrets # root = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES) # secrets = generateSecrets(root=root, count=8) # Direct Mode initiated by coe is controller, val is validator # but goes both ways once initiated. # set of secrets (seeds for private keys) coeSalt = Salter(raw=b'0123456789abcdea').qb64 # set of secrets (seeds for private keys) valSalt = Salter(raw=b'1123456789abcdea').qb64 with openDB("controller") as coeLogger, openDB("validator") as valLogger, \ openKS(name="controller") as coeKpr, openKS(name="validator") as valKpr: # Init key pair manager coeMgr = Manager(keeper=coeKpr, salt=coeSalt) coeVerfers, coeDigers, cst, nst = coeMgr.incept(icount=1, ncount=1) # init Keverys coeKevery = eventing.Kevery(db=coeLogger) valKevery = eventing.Kevery(db=valLogger) coe_event_digs = [] # list of controller's own event log digs to verify against database val_event_digs = [] # list of validator's own event log digs to verify against database # init sequence numbers for both controller and validator csn = cesn = 0 # sn and last establishment sn = esn vsn = vesn = 0 # sn and last establishment sn = esn # Controller Event 0 Inception Transferable (nxt digest not empty) coeSerder = incept(keys=[coeVerfers[0].qb64], nxt=eventing.Nexter(digs=[coeDigers[0].qb64]).qb64, code=MtrDex.Blake3_256) assert csn == int(coeSerder.ked["s"], 16) == 0 coepre = coeSerder.ked["i"] coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(ser=coeSerder.raw, verfers=coeVerfers) # create serialized message cmsg = messagize(coeSerder, sigers=sigers) # create own Controller Kever in Controller's Kevery parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery) # coeKevery.processOne(ims=bytearray(cmsg)) # send copy of cmsg coeKever = coeKevery.kevers[coepre] assert coeKever.prefixer.qb64 == coepre # Validator Event 0 Inception Transferable (nxt digest not empty) # Init key pair manager valMgr = Manager(keeper=valKpr, salt=valSalt) valVerfers, valDigers, cst, nst = valMgr.incept(icount=1, ncount=1) valSerder = incept(keys=[valVerfers[0].qb64], nxt=eventing.Nexter(digs=[valDigers[0].qb64]).qb64, code=MtrDex.Blake3_256) assert vsn == int(valSerder.ked["s"], 16) == 0 valpre = valSerder.ked["i"] val_event_digs.append(valSerder.dig) # sign serialization sigers = valMgr.sign(valSerder.raw, verfers=valVerfers) # return Siger if index # create serialized message vmsg = messagize(valSerder, sigers=sigers) # create own Validator Kever in Validator's Kevery parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery) # valKevery.processOne(ims=bytearray(vmsg)) # send copy of vmsg valKever = valKevery.kevers[valpre] assert valKever.prefixer.qb64 == valpre # simulate sending of controller's inception message to validator parsing.Parser().parse(ims=bytearray(cmsg), kvy=valKevery) # valKevery.process(ims=bytearray(cmsg)) # make copy of msg assert coepre in valKevery.kevers # creates Kever for controller in validator's .kevers # create receipt of controller's inception # create seal of validator's last establishment event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) coeK = valKevery.kevers[coepre] # lookup coeKever from validator's .kevers # create trans receipt reserder = receipt(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64) #reserder = chit(pre=coeK.prefixer.qb64, #sn=coeK.sn, #dig=coeK.serder.diger.qb64, #seal=seal) # Validate receipt # sign controller's event not receipt # look up event to sign from validator's kever for coe coeIcpDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeIcpDig == coeK.serder.diger.qb64b coeIcpRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIcpDig))) #counter = Counter(CtrDex.ControllerIdxSigs) #assert counter.qb64 == '-AAB' sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers) # return Siger if index # process own validator receipt in validator's Kevery so have copy in own log rmsg = messagize(reserder, sigers=sigers, seal=seal) assert len(rmsg) == 353 parsing.Parser().parseOne(ims=bytearray(rmsg), kvy=valKevery) # valKevery.processOne(ims=bytearray(rmsg)) # process copy of rmsg # attach receipt message to existing message with validators inception message # simulate streaming. validator first sends it's inception event, then sends a receipt to controller vmsg.extend(rmsg) # Simulate sending validator's inception event and receipt of # controller's inception message to controller parsing.Parser().parse(ims=vmsg, kvy=coeKevery) # coeKevery.process(ims=vmsg) # controller process validator's inception and receipt # check if validator's Kever in controller's .kevers assert valpre in coeKevery.kevers # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) # create receipt to escrow use invalid digest and sequence number so not in controller's db fake = reserder.dig # some other digest reserder = receipt(pre=coeK.prefixer.qb64, sn=10, dig=fake) # sign event not receipt sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers) # return Siger if index # create receipt message vmsg = messagize(reserder, sigers=sigers, seal=seal) parsing.Parser().parse(ims=bytearray(vmsg), kvy=coeKevery) # coeKevery.process(ims=vmsg) # controller process the escrow receipt from validator # check if receipt quadruple in escrow database result = coeKevery.db.getVres(key=snKey(pre=coeKever.prefixer.qb64, sn=10)) assert bytes(result[0]) == (fake.encode("utf-8") + valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) # Send receipt from controller to validator # create receipt of validator's inception # create seal of controller's last establishment event seal = SealEvent(i=coepre, s="{:x}".format(coeKever.lastEst.s), d=coeKever.lastEst.d) valK = coeKevery.kevers[valpre] # lookup valKever from controller's .kevers # create trans receipt reserder = receipt(pre=valK.prefixer.qb64, sn=valK.sn, dig=valK.serder.diger.qb64,) # sign validator's event not receipt # look up event to sign from controller's kever for validator valIcpDig = bytes(coeKevery.db.getKeLast(key=snKey(pre=valpre, sn=vsn))) assert valIcpDig == valK.serder.diger.qb64b valIcpRaw = bytes(coeKevery.db.getEvt(key=dgKey(pre=valpre, dig=valIcpDig))) sigers = coeMgr.sign(ser=valIcpRaw, verfers=coeVerfers) # return Siger if index # create receipt message cmsg = messagize(reserder, sigers=sigers, seal=seal) # controller process own receipt in own Kevery so have copy in own log parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery) # coeKevery.processOne(ims=bytearray(cmsg)) # make copy # Simulate sending controller's receipt of validator's inception message to validator parsing.Parser().parse(ims=cmsg, kvy=valKevery) # valKevery.process(ims=cmsg) # controller process validator's inception and receipt # check if receipt quadruple from controller in validator's receipt database result = valKevery.db.getVrcs(key=dgKey(pre=valKever.prefixer.qb64, dig=valKever.serder.diger.qb64)) assert bytes(result[0]) == (coeKever.prefixer.qb64b + Seqner(sn=coeKever.sn).qb64b + coeKever.serder.diger.qb64b + sigers[0].qb64b) # Controller Event 1 Rotation Transferable csn += 1 cesn += 1 assert csn == cesn == 1 coeVerfers, coeDigers, cst, nst = coeMgr.rotate(pre=coeVerfers[0].qb64) coeSerder = rotate(pre=coeKever.prefixer.qb64, keys=[coeVerfers[0].qb64], dig=coeKever.serder.diger.qb64, nxt=eventing.Nexter(digs=[coeDigers[0].qb64]).qb64, sn=csn) coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers) # returns sigers # create serialized message cmsg = messagize(coeSerder, sigers=sigers) # update controller's key event verifier state parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery) # coeKevery.processOne(ims=bytearray(cmsg)) # make copy # verify controller's copy of controller's event stream is updated assert coeKever.sn == csn assert coeKever.serder.diger.qb64 == coeSerder.dig # simulate send message from controller to validator parsing.Parser().parse(ims=cmsg, kvy=valKevery) # valKevery.process(ims=cmsg) # verify validator's copy of controller's event stream is updated assert coeK.sn == csn assert coeK.serder.diger.qb64 == coeSerder.dig # create receipt of controller's rotation # create seal of validator's last establishment event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) # create validator receipt reserder = receipt(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64) # sign controller's event not receipt # look up event to sign from validator's kever for controller coeRotDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeRotDig == coeK.serder.diger.qb64b coeRotRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeRotDig))) sigers = valMgr.sign(ser=coeRotRaw, verfers=valVerfers) # validator create receipt message vmsg = messagize(reserder, sigers=sigers, seal=seal) # validator process own receipt in own kevery so have copy in own log parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery) # valKevery.processOne(ims=bytearray(vmsg)) # make copy # Simulate send to controller of validator's receipt of controller's rotation message parsing.Parser().parse(ims=vmsg, kvy=coeKevery) # coeKevery.process(ims=vmsg) # controller process validator's incept and receipt # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) # Next Event 2 Controller Interaction csn += 1 # do not increment esn assert csn == 2 assert cesn == 1 coeSerder = interact(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64, sn=csn) coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers) # create msg cmsg = messagize(coeSerder, sigers=sigers) # update controller's key event verifier state parsing.Parser().parseOne(ims=bytearray(cmsg), kvy=coeKevery) # coeKevery.processOne(ims=bytearray(cmsg)) # make copy # verify controller's copy of controller's event stream is updated assert coeKever.sn == csn assert coeKever.serder.diger.qb64 == coeSerder.dig # simulate send message from controller to validator parsing.Parser().parse(ims=cmsg, kvy=valKevery) # valKevery.process(ims=cmsg) # verify validator's copy of controller's event stream is updated assert coeK.sn == csn assert coeK.serder.diger.qb64 == coeSerder.dig # create receipt of controller's interaction # create seal of validator's last est event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) # create validator receipt reserder = receipt(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64) # sign controller's event not receipt # look up event to sign from validator's kever for controller coeIxnDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeIxnDig == coeK.serder.diger.qb64b coeIxnRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIxnDig))) sigers = valMgr.sign(ser=coeIxnRaw, verfers=valVerfers) # create receipt message vmsg = messagize(reserder, sigers=sigers, seal=seal) # validator process own receipt in own kevery so have copy in own log parsing.Parser().parseOne(ims=bytearray(vmsg), kvy=valKevery) # valKevery.processOne(ims=bytearray(vmsg)) # make copy # Simulate send to controller of validator's receipt of controller's rotation message parsing.Parser().parse(ims=bytearray(vmsg), kvy=coeKevery) # coeKevery.process(ims=vmsg) # controller process validator's incept and receipt # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) # verify final controller event state assert coeKever.sn == coeK.sn == csn db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(coepre)] assert len(db_digs) == len(coe_event_digs) == csn + 1 assert db_digs == coe_event_digs db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(coepre)] assert len(db_digs) == len(coe_event_digs) == csn + 1 assert db_digs == coe_event_digs # verify final validator event state assert valKever.sn == valK.sn == vsn db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(valpre)] assert len(db_digs) == len(val_event_digs) == vsn + 1 assert db_digs == val_event_digs db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(valpre)] assert len(db_digs) == len(val_event_digs) == vsn + 1 assert db_digs == val_event_digs assert not os.path.exists(valKevery.db.path) assert not os.path.exists(coeKever.baser.path)
def test_direct_mode_with_manager(): """ Test direct mode with transferable validator event receipts """ # manual process to generate a list of secrets # root = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES) # secrets = generateSecrets(root=root, count=8) # Direct Mode initiated by coe is controller, val is validator # but goes both ways once initiated. # set of secrets (seeds for private keys) coeSalt = Salter(raw=b'0123456789abcdea').qb64 # set of secrets (seeds for private keys) valSalt = Salter(raw=b'1123456789abcdea').qb64 with openDB("controller") as coeLogger, openDB("validator") as valLogger, openKS(name="controller") as coeKpr, openKS(name="validator") as valKpr: # Init key pair manager coeMgr = Manager(keeper=coeKpr, salt=coeSalt) coeVerfers, coeDigers = coeMgr.incept(icount=1, ncount=1) # init Keverys coeKevery = Kevery(db=coeLogger) valKevery = Kevery(db=valLogger) coe_event_digs = [] # list of controller's own event log digs to verify against database val_event_digs = [] # list of validator's own event log digs to verify against database # init sequence numbers for both controller and validator csn = cesn = 0 # sn and last establishment sn = esn vsn = vesn = 0 # sn and last establishment sn = esn # Controller Event 0 Inception Transferable (nxt digest not empty) coeSerder = incept(keys=[coeVerfers[0].qb64], nxt=Nexter(digs=[coeDigers[0].qb64]).qb64, code=MtrDex.Blake3_256) assert csn == int(coeSerder.ked["s"], 16) == 0 coepre = coeSerder.ked["i"] assert coepre == 'EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas' coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(ser=coeSerder.raw, verfers=coeVerfers) # create serialized message cmsg = messagize(coeSerder, sigers) assert cmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"0","t":"icp","kt":"1","k":["Dpt7mGZ3y5UmhT1NLEx' b'b1IW8vMJ8ylQW3K44LfkTgAqE"],"n":"Erpltchg7BUv21Qz3ZXhOhVu63m7S7Y' b'bPb21lSeGYd90","wt":"0","w":[],"c":[]}-AABAA2dW-FXhcUiGQZh1JhRrh' b'_JDqEPU678KT0U8F_a-l8Q3sO25xJAs3Iu2bBonBPZjVo_Zc8FVqrqXjQxxUPt4ICg') # create own Controller Kever in Controller's Kevery coeKevery.processOne(ims=bytearray(cmsg)) # send copy of cmsg coeKever = coeKevery.kevers[coepre] assert coeKever.prefixer.qb64 == coepre # Validator Event 0 Inception Transferable (nxt digest not empty) # Init key pair manager valMgr = Manager(keeper=valKpr, salt=valSalt) valVerfers, valDigers = valMgr.incept(icount=1, ncount=1) valSerder = incept(keys=[valVerfers[0].qb64], nxt=Nexter(digs=[valDigers[0].qb64]).qb64, code=MtrDex.Blake3_256) assert vsn == int(valSerder.ked["s"], 16) == 0 valpre = valSerder.ked["i"] assert valpre == 'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0' val_event_digs.append(valSerder.dig) # sign serialization sigers = valMgr.sign(valSerder.raw, verfers=valVerfers) # return Siger if index # create serialized message vmsg = messagize(valSerder, sigers) assert vmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF' b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA' b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl' b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}-AABAAxvl1581mKQME95XZrjsy' b'CXxJ3fCnmNSG_Bc1I4FcxEoeQbgdLAQ8sudwb0FHOYXfqRE6Z7PraaU82YQDyVShDw') # create own Validator Kever in Validator's Kevery valKevery.processOne(ims=bytearray(vmsg)) # send copy of vmsg valKever = valKevery.kevers[valpre] assert valKever.prefixer.qb64 == valpre # simulate sending of controller's inception message to validator valKevery.process(ims=bytearray(cmsg)) # make copy of msg assert coepre in valKevery.kevers # creates Kever for controller in validator's .kevers # create receipt of controller's inception # create seal of validator's last establishment event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) coeK = valKevery.kevers[coepre] # lookup coeKever from validator's .kevers # create validator receipt reserder = chit(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64, seal=seal) # Validate receipt assert reserder.raw == (b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",' b'"s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","a":{"i' b'":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7x' b'HnuE-wyiarIZ9j-1CEQ89I0E3WevcE"}}') # sign controller's event not receipt # look up event to sign from validator's kever for coe coeIcpDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeIcpDig == coeK.serder.diger.qb64b == b'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc' coeIcpRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIcpDig))) assert coeIcpRaw == (b'{"v":"KERI10JSON0000e6_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",' b'"s":"0","t":"icp","kt":"1","k":["Dpt7mGZ3y5UmhT1NLExb1IW8vMJ8ylQW3K44LfkTgAq' b'E"],"n":"Erpltchg7BUv21Qz3ZXhOhVu63m7S7YbPb21lSeGYd90","wt":"0","w":[],"c":[' b']}') counter = Counter(CtrDex.ControllerIdxSigs) assert counter.qb64 == '-AAB' sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers) # return Siger if index # process own validator receipt in validator's Kevery so have copy in own log rmsg = messagize(reserder, sigers) assert rmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",' b'"s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","a":{"i' b'":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7x' b'HnuE-wyiarIZ9j-1CEQ89I0E3WevcE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwy' b'qst_ZvLo05jau9GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA') valKevery.processOne(ims=bytearray(rmsg)) # process copy of rmsg # attach receipt message to existing message with validators inception message # simulate streaming. validator first sends it's inception event, then sends a receipt to controller vmsg.extend(rmsg) assert vmsg == bytearray(b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF' b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA' b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl' b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}-AABAAxvl1581mKQME95XZrjsy' b'CXxJ3fCnmNSG_Bc1I4FcxEoeQbgdLAQ8sudwb0FHOYXfqRE6Z7PraaU82YQDyVSh' b'Dw{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14Vk' b'BOCJnPYabcas","s":"0","t":"vrc","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us' b'-0juFL5hOAHAwIEkc","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFB' b'DyVSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3W' b'evcE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyqst_ZvLo05jau9' b'GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA') # Simulate sending validator's inception event and receipt of controller's inception message to controller coeKevery.process(ims=vmsg) # controller process validator's inception and receipt # check if validator's Kever in controller's .kevers assert valpre in coeKevery.kevers # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ' b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyq' b'st_ZvLo05jau9GsF0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA') # create receipt to escrow use invalid digest and sequence number so not in controller's db fake = reserder.dig # some other digest reserder = chit(pre=coeK.prefixer.qb64, sn=10, dig=fake, seal=seal) # sign event not receipt sigers = valMgr.sign(ser=coeIcpRaw, verfers=valVerfers) # return Siger if index # create receipt message vmsg = messagize(reserder, sigers) assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"a","t":"vrc","d":"EwxY7Vhkeyr7LBnLAzdGXZzSmTmJV' b'RctQfNUO0YUqeOU","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy' b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev' b'cE"}}-AABAARG0my55RTX81fFzUbbcfygZXfz04VglNA8Zwyqst_ZvLo05jau9Gs' b'F0IS9Vm6yGr8QQPdB7M4oVkrd9IEZ8PDA') coeKevery.process(ims=vmsg) # controller process the escrow receipt from validator # check if receipt quadruple in escrow database result = coeKevery.db.getVres(key=snKey(pre=coeKever.prefixer.qb64, sn=10)) assert bytes(result[0]) == (fake.encode("utf-8") + valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) # Send receipt from controller to validator # create receipt of validator's inception # create seal of controller's last establishment event seal = SealEvent(i=coepre, s="{:x}".format(coeKever.lastEst.s), d=coeKever.lastEst.d) valK = coeKevery.kevers[valpre] # lookup valKever from controller's .kevers # create validator receipt reserder = chit(pre=valK.prefixer.qb64, sn=valK.sn, dig=valK.serder.diger.qb64, seal=seal) # sign validator's event not receipt # look up event to sign from controller's kever for validator valIcpDig = bytes(coeKevery.db.getKeLast(key=snKey(pre=valpre, sn=vsn))) assert valIcpDig == valK.serder.diger.qb64b == b'ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcE' valIcpRaw = bytes(coeKevery.db.getEvt(key=dgKey(pre=valpre, dig=valIcpDig))) assert valIcpRaw == (b'{"v":"KERI10JSON0000e6_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF' b'BDyVSOXYW0","s":"0","t":"icp","kt":"1","k":["DLSBUmklGu6eLqnA5DA' b'gj41jetAJYkyn34crqejwXxVw"],"n":"EwmUJaS6DSPRQprlGp_3CIg8BZwmaJl' b'KPlE4LHcx0Zms","wt":"0","w":[],"c":[]}') counter = Counter(CtrDex.ControllerIdxSigs) assert counter.qb64 == '-AAB' sigers = coeMgr.sign(ser=valIcpRaw, verfers=coeVerfers) # return Siger if index # create receipt message cmsg = messagize(reserder, sigers) assert cmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqF' b'BDyVSOXYW0","s":"0","t":"vrc","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-' b'1CEQ89I0E3WevcE","a":{"i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJn' b'PYabcas","s":"0","d":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIE' b'kc"}}-AABAAKXFMBGw559YHoxyeDrmpilQo5JMbr5WSfYTn1IXV_rMtg23_GHrNQ' b'Ua7y45UkNftT48O0MekxT7geRBU84dACA') # controller process own receipt in own Kevery so have copy in own log coeKevery.processOne(ims=bytearray(cmsg)) # make copy # Simulate sending controller's receipt of validator's inception message to validator valKevery.process(ims=cmsg) # controller process validator's inception and receipt # check if receipt quadruple from controller in validator's receipt database result = valKevery.db.getVrcs(key=dgKey(pre=valKever.prefixer.qb64, dig=valKever.serder.diger.qb64)) assert bytes(result[0]) == (coeKever.prefixer.qb64b + Seqner(sn=coeKever.sn).qb64b + coeKever.serder.diger.qb64b + sigers[0].qb64b) assert bytes(result[0]) == (b'EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas0AAAAAAAAAAAAAAAAAAAAAAAEy2pXEna' b'oQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkcAAKXFMBGw559YHoxyeDrmpilQo5JMbr5WSfYTn1I' b'XV_rMtg23_GHrNQUa7y45UkNftT48O0MekxT7geRBU84dACA') # Controller Event 1 Rotation Transferable csn += 1 cesn += 1 assert csn == cesn == 1 coeVerfers, coeDigers = coeMgr.rotate(coeVerfers[0].qb64) coeSerder = rotate(pre=coeKever.prefixer.qb64, keys=[coeVerfers[0].qb64], dig=coeKever.serder.diger.qb64, nxt=Nexter(digs=[coeDigers[0].qb64]).qb64, sn=csn) coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers) # returns sigers # create serialized message cmsg = messagize(coeSerder, sigers) assert cmsg == bytearray(b'{"v":"KERI10JSON000122_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"1","t":"rot","p":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0' b'juFL5hOAHAwIEkc","kt":"1","k":["D-HwiqmaETxls3vAVSh0xpXYTs94NUJX' b'6juupWj_EgsA"],"n":"ED6lKZwg-BWl_jlCrjosQkOEhqKD4BJnlqYqWmhqPhaU' b'","wt":"0","wr":[],"wa":[],"a":[]}-AABAAsDhyw43CAo29zyTZ7WIuztBG' b'L3WELM78qSwaEYh8NzwNAPqDtiuL-QmKd22om1qYGDU7cuFM-AlTKaFjsVOzBg') # update controller's key event verifier state coeKevery.processOne(ims=bytearray(cmsg)) # make copy # verify controller's copy of controller's event stream is updated assert coeKever.sn == csn assert coeKever.serder.diger.qb64 == coeSerder.dig # simulate send message from controller to validator valKevery.process(ims=cmsg) # verify validator's copy of controller's event stream is updated assert coeK.sn == csn assert coeK.serder.diger.qb64 == coeSerder.dig # create receipt of controller's rotation # create seal of validator's last establishment event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) # create validator receipt reserder = chit(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64, seal=seal) # sign controller's event not receipt # look up event to sign from validator's kever for controller coeRotDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeRotDig == coeK.serder.diger.qb64b == b'EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek' coeRotRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeRotDig))) assert coeRotRaw == (b'{"v":"KERI10JSON000122_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",' b'"s":"1","t":"rot","p":"Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc","kt":"1' b'","k":["D-HwiqmaETxls3vAVSh0xpXYTs94NUJX6juupWj_EgsA"],"n":"ED6lKZwg-BWl_jlC' b'rjosQkOEhqKD4BJnlqYqWmhqPhaU","wt":"0","wr":[],"wa":[],"a":[]}') sigers = valMgr.sign(ser=coeRotRaw, verfers=valVerfers) # validator create receipt message vmsg = messagize(reserder, sigers) assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"1","t":"vrc","d":"EO7V6wDClWWiN_7sfGDTD8KsfRQaH' b'yap6fz_O4CYvsek","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy' b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev' b'cE"}}-AABAAjVFBjhbM2RdHKEk2rtHA0tXMe0iswn6IS5ShALtR3JHMz-NePCN_f' b'lUEUbV2F22CGRgmnCe71n42ywWyzsFmDg') # validator process own receipt in own kevery so have copy in own log valKevery.processOne(ims=bytearray(vmsg)) # make copy # Simulate send to controller of validator's receipt of controller's rotation message coeKevery.process(ims=vmsg) # controller process validator's incept and receipt # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ' b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAAjVFBjhbM2RdHKEk2rtHA0tXMe0iswn6IS5ShAL' b'tR3JHMz-NePCN_flUEUbV2F22CGRgmnCe71n42ywWyzsFmDg') # Next Event 2 Controller Interaction csn += 1 # do not increment esn assert csn == 2 assert cesn == 1 coeSerder = interact(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64, sn=csn) coe_event_digs.append(coeSerder.dig) # sign serialization sigers = coeMgr.sign(coeSerder.raw, verfers=coeVerfers) # create msg cmsg = messagize(coeSerder, sigers) assert cmsg == bytearray(b'{"v":"KERI10JSON000098_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"2","t":"ixn","p":"EO7V6wDClWWiN_7sfGDTD8KsfRQaH' b'yap6fz_O4CYvsek","a":[]}-AABAAstaU9Hu1ti8erlnFwEdCrXWkkkW_ydYgrr' b'ryB6EtEOrWY_tQh5jZLGRWrClefeX6AfDDw7JS5JY15n8_ueJWBQ') # update controller's key event verifier state coeKevery.processOne(ims=bytearray(cmsg)) # make copy # verify controller's copy of controller's event stream is updated assert coeKever.sn == csn assert coeKever.serder.diger.qb64 == coeSerder.dig # simulate send message from controller to validator valKevery.process(ims=cmsg) # verify validator's copy of controller's event stream is updated assert coeK.sn == csn assert coeK.serder.diger.qb64 == coeSerder.dig # create receipt of controller's interaction # create seal of validator's last est event seal = SealEvent(i=valpre, s="{:x}".format(valKever.lastEst.s), d=valKever.lastEst.d) # create validator receipt reserder = chit(pre=coeK.prefixer.qb64, sn=coeK.sn, dig=coeK.serder.diger.qb64, seal=seal) # sign controller's event not receipt # look up event to sign from validator's kever for controller coeIxnDig = bytes(valKevery.db.getKeLast(key=snKey(pre=coepre, sn=csn))) assert coeIxnDig == coeK.serder.diger.qb64b == b'EuCLxtdKdRgzzgBnPhTwFKz36u58DqQyMqhX5CUrurPE' coeIxnRaw = bytes(valKevery.db.getEvt(key=dgKey(pre=coepre, dig=coeIxnDig))) assert coeIxnRaw == (b'{"v":"KERI10JSON000098_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBOCJnPYabcas",' b'"s":"2","t":"ixn","p":"EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek","a":[]}') sigers = valMgr.sign(ser=coeIxnRaw, verfers=valVerfers) # create receipt message vmsg = messagize(reserder, sigers) assert vmsg == bytearray(b'{"v":"KERI10JSON000105_","i":"EsU9ZQwug7DS-GU040Ugj1t7p6Au14VkBO' b'CJnPYabcas","s":"2","t":"vrc","d":"EuCLxtdKdRgzzgBnPhTwFKz36u58D' b'qQyMqhX5CUrurPE","a":{"i":"EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDy' b'VSOXYW0","s":"0","d":"ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3Wev' b'cE"}}-AABAAboeSfNNgX04wuUrQp-3eY0oUzcLYnLUmtqYETBZqXEL97pjSjmm81' b'1KzCRu2cnSHVlKqzIaEBaXyBpWBDexLBQ') # ------------------------------END CONVERTED CODE------------------------------ # validator process own receipt in own kevery so have copy in own log valKevery.processOne(ims=bytearray(vmsg)) # make copy # Simulate send to controller of validator's receipt of controller's rotation message coeKevery.process(ims=vmsg) # controller process validator's incept and receipt # check if receipt quadruple from validator in receipt database result = coeKevery.db.getVrcs(key=dgKey(pre=coeKever.prefixer.qb64, dig=coeKever.serder.diger.qb64)) assert bytes(result[0]) == (valKever.prefixer.qb64b + Seqner(sn=valKever.sn).qb64b + valKever.serder.diger.qb64b + sigers[0].qb64b) assert bytes(result[0]) == (b'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW00AAAAAAAAAAAAAAAAAAAAAAAElsHFkbZ' b'QjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcEAAboeSfNNgX04wuUrQp-3eY0oUzcLYnLUmtqYETB' b'ZqXEL97pjSjmm811KzCRu2cnSHVlKqzIaEBaXyBpWBDexLBQ') # verify final controller event state assert coeKever.sn == coeK.sn == csn db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(coepre)] assert len(db_digs) == len(coe_event_digs) == csn + 1 assert db_digs == coe_event_digs == ['Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc', 'EO7V6wDClWWiN_7sfGDTD8KsfRQaHyap6fz_O4CYvsek', 'EuCLxtdKdRgzzgBnPhTwFKz36u58DqQyMqhX5CUrurPE'] db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(coepre)] assert len(db_digs) == len(coe_event_digs) == csn + 1 assert db_digs == coe_event_digs # verify final validator event state assert valKever.sn == valK.sn == vsn db_digs = [bytes(v).decode("utf-8") for v in valKever.baser.getKelIter(valpre)] assert len(db_digs) == len(val_event_digs) == vsn + 1 assert db_digs == val_event_digs == ['ElsHFkbZQjRb7xHnuE-wyiarIZ9j-1CEQ89I0E3WevcE'] db_digs = [bytes(v).decode("utf-8") for v in coeKever.baser.getKelIter(valpre)] assert len(db_digs) == len(val_event_digs) == vsn + 1 assert db_digs == val_event_digs assert not os.path.exists(valKevery.db.path) assert not os.path.exists(coeKever.baser.path)
def test_tevery(): with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[], toad=0, cnfg=["NB"], code=MtrDex.Blake3_256) regk = vcp.pre # successfully anchor to a rotation event rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tvy = Tevery(reger=reg, db=db) tvy.processEvent(serder=vcp, seqner=seqner, diger=diger) assert regk in tvy.tevers tev = tvy.tevers[regk] assert tev.prefixer.qb64 == vcp.pre assert tev.sn == 0 # send vcp again, get error with pytest.raises(LikelyDuplicitousError): tvy.processEvent(serder=vcp, seqner=seqner, diger=diger) # process issue vc event vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU' iss = eventing.issue(vcdig=vcdig.decode("utf-8"), regk=regk) # successfully anchor to a rotation event rseal = SealEvent(iss.ked["i"], iss.ked["s"], iss.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tvy.processEvent(serder=iss, seqner=seqner, diger=diger) assert tev.vcState(vcdig) == VcStates.issued assert tev.vcSn(vcdig) == 0 # revoke the vc rev = eventing.revoke(vcdig=vcdig.decode("utf-8"), regk=regk, dig=iss.dig) # successfully anchor to a rotation event rseal = SealEvent(rev.ked["i"], rev.ked["s"], rev.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tvy.processEvent(serder=rev, seqner=seqner, diger=diger) assert tev.vcState(vcdig) == VcStates.revoked assert tev.vcSn(vcdig) == 1
def test_tever_backers(mockHelpingNowUTC): # registry with backer and receipt with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: valSecret = 'AgjD4nRlycmM5cPcAkfOATAp8wVldRsnc9f1tiwctXlw' # create receipt signer prefixer default code is non-transferable valSigner = Signer(qb64=valSecret, transferable=False) valPrefixer = Prefixer(qb64=valSigner.verfer.qb64) valpre = valPrefixer.qb64 assert valpre == 'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc' hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[valpre], toad=1, cnfg=[], code=MtrDex.Blake3_256) regk = vcp.pre valCigar = valSigner.sign(ser=vcp.raw, index=0) # successfully anchor to a rotation event rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev = Tever(serder=vcp, seqner=seqner, diger=diger, bigers=[valCigar], db=db, reger=reg) dgkey = dgKey(pre=regk, dig=vcp.dig) assert reg.getTvt(dgkey) == ( b'{"v":"KERI10JSON0000d7_","i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU",' b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],' b'"bt":"1",' b'"b":["B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc"]}') assert reg.getAnc( dgkey ) == b'0AAAAAAAAAAAAAAAAAAAAAAQEpWPsFsCcsu5SpVH0416qHx3gvG0CWlrP_i7BVdbmRBg' assert reg.getTel(snKey( pre=regk, sn=0)) == b'EJTWiS0ebp8VSyLr38x73dAHdUqivisUtAaGpEHt5HDc' assert [bytes(tib) for tib in reg.getTibs(dgkey)] == [ b'AAGhpPxAoltsRAnqxf7NsBzWSxWYLZ_ALImVVBiTlzJSdlATxRp_hBK4AbOzu-a900hwRxa0RX-yVWbVJA6oxoBw' ] assert reg.getTwe(snKey(pre=regk, sn=0)) is None debSecret = 'AKUotEE0eAheKdDJh9QvNmSEmO_bjIav8V_GmctGpuCQ' # create receipt signer prefixer default code is non-transferable debSigner = Signer(qb64=debSecret, transferable=False) debPrefixer = Prefixer(qb64=debSigner.verfer.qb64) debpre = debPrefixer.qb64 assert debpre == 'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI' vrt = eventing.rotate(regk, dig=vcp.dig, baks=[valpre], adds=[debpre]) valCigar = valSigner.sign(ser=vrt.raw, index=0) debCigar = debSigner.sign(ser=vrt.raw, index=1) # successfully anchor to a rotation event rseal = SealEvent(regk, vrt.ked["s"], vrt.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(serder=vrt, seqner=seqner, diger=diger, bigers=[valCigar, debCigar]) assert tev.baks == [ 'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc', 'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI' ] vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU' bis = eventing.backerIssue(vcdig=vcdig.decode("utf-8"), regk=regk, regsn=tev.sn, regd=tev.serder.dig) valCigar = valSigner.sign(ser=bis.raw, index=0) debCigar = debSigner.sign(ser=bis.raw, index=1) # successfully anchor to a rotation event rseal = SealEvent(bis.ked["i"], bis.ked["s"], bis.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(bis, seqner=seqner, diger=diger, bigers=[valCigar, debCigar]) vci = nsKey([regk, vcdig]) dgkey = dgKey(pre=vci, dig=bis.dig) assert bytes(reg.getTvt(dgkey)) == ( b'{"v":"KERI10JSON00012d_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",' b'"ii":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":"0","t":"bis","ra":{' b'"i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":1,"d":"EZH2Cfw3nvcMRg' b'Y31Jyc2zHVh4a0LO_bVZ4EmL4V8Ol8"},"dt":"2021-01-01T00:00:00.000000+00:00"}' )
def test_tever_no_backers(mockHelpingNowUTC): # registry with no backers # registry with backer and receipt with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[], toad=0, cnfg=["NB"], code=MtrDex.Blake3_256) regk = vcp.pre # successfully anchor to a rotation event rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev = Tever(serder=vcp, seqner=seqner, diger=diger, db=db, reger=reg) assert tev.prefixer.qb64 == vcp.pre assert tev.sn == 0 dgkey = dgKey(pre=regk, dig=vcp.dig) assert reg.getTvt(dgkey) == ( b'{"v":"KERI10JSON0000ad_","i":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw",' b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":["NB"],"bt":"0","b":[]}' ) assert reg.getAnc(dgkey) == ( b'0AAAAAAAAAAAAAAAAAAAAAAQE-yQ6BjCaJg-u2mNuE-ycVWVTq7IZ8TuN-Ew8soLijSA' ) assert reg.getTel(snKey( pre=regk, sn=0)) == b'ElYstqTocyQixLLz4zYCAs2unaFco_p6LqH0W01loIg4' assert reg.getTibs(dgkey) == [] assert reg.getTwe(snKey(pre=regk, sn=0)) is None # try to rotate a backerless registry vrt = eventing.rotate(regk, dig=vcp.dig) rseal = SealEvent(regk, vrt.ked["s"], vrt.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger # should raise validation err because rotation is not supported with pytest.raises(ValidationError): tev.update(serder=vrt, seqner=seqner, diger=diger) vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU' iss = eventing.issue(vcdig=vcdig.decode("utf-8"), regk=regk) # successfully anchor to a rotation event rseal = SealEvent(iss.ked["i"], iss.ked["s"], iss.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(iss, seqner=seqner, diger=diger) vci = nsKey([regk, vcdig]) dgkey = dgKey(pre=vci, dig=iss.dig) assert bytes(reg.getTvt(dgkey)) == ( b'{"v":"KERI10JSON0000ba_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",' b'"s":"0","t":"iss","ri":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw","dt":"' b'2021-01-01T00:00:00.000000+00:00"}') assert bytes( reg.getAnc(dgkey) ) == b'0AAAAAAAAAAAAAAAAAAAAAAwEJLLpuUKPSDIcoOAOArQBzceWc8MoShm-cDL-w81liIw' # revoke vc with no backers rev = eventing.revoke(vcdig=vcdig.decode("utf-8"), regk=regk, dig=iss.dig) # successfully anchor to a rotation event rseal = SealEvent(rev.ked["i"], rev.ked["s"], rev.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(rev, seqner=seqner, diger=diger) dgkey = dgKey(pre=vci, dig=rev.dig) assert bytes(reg.getTvt(dgkey)) == ( b'{"v":"KERI10JSON0000ed_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",' b'"s":"1","t":"rev","ri":"Ezm53Qww2LTJ1yksEL06Wtt-5D23QKdJEGI0egFyLehw","p":"E' b'C9PffPrvyaKzsn72SWTvgyvWCJ1FbDThvJhsQ9LWo9M","dt":"2021-01-01T00:00:00.00000' b'0+00:00"}')
def test_tever_escrow(): with pytest.raises(TypeError): Tever() # registry with no backers, invalid anchor with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[], toad=0, cnfg=[], code=MtrDex.Blake3_256) regk = vcp.pre assert regk == "EoN_Ln_JpgqsIys-jDOH8oWdxgWqs7hzkDGeLWHb9vSY" assert vcp.dig == "EvpB-_BWD7tOhLI0cDyEQbziBt6IMyQnkrh0booR4vhg" assert vcp.ked["ii"] == hab.pre # anchor to nothing, exception expected seqner = Seqner(sn=4) # invalid seal sn with pytest.raises(ValidationError): Tever(serder=vcp, seqner=seqner, diger=None, db=db, reger=reg) # registry with no backers with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[], toad=0, cnfg=[], code=MtrDex.Blake3_256) regk = vcp.pre # anchoring event not in db, exception and escrow seqner = Seqner(sn=1) with pytest.raises(MissingAnchorError): Tever(serder=vcp, seqner=seqner, db=db, reger=reg) dgkey = dgKey(pre=regk, dig=vcp.dig) assert reg.getTvt(dgkey) == ( b'{"v":"KERI10JSON0000a9_","i":"EoN_Ln_JpgqsIys-jDOH8oWdxgWqs7hzkDGeLWHb9vSY",' b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],"bt":"0","b":[]}' ) assert reg.getTae(snKey( pre=regk, sn=0)) == b'EvpB-_BWD7tOhLI0cDyEQbziBt6IMyQnkrh0booR4vhg' # registry with backers, no signatures. should escrow with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: hab = buildHab(db, kpr) vcp = eventing.incept( hab.pre, baks=["BoOcciw30IVQsaenKXpiyMVrjtPDW3KeD_6KFnSfoaqI"], toad=1, cnfg=[], code=MtrDex.Blake3_256) regk = vcp.pre # successfully anchor to a rotation event rseal = SealEvent(regk, vcp.ked["s"], vcp.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger with pytest.raises(MissingWitnessSignatureError): Tever(serder=vcp, seqner=seqner, diger=diger, db=db, reger=reg) dgkey = dgKey(pre=regk, dig=vcp.dig) assert reg.getTvt(dgkey) == ( b'{"v":"KERI10JSON0000d7_","i":"E1cv04kvHvWPrfncYsq-lQ-QvyKmKz6-hlGj02B2QWbk",' b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],"bt":"1",' b'"b":["BoOcciw30IVQsaenKXpiyMVrjtPDW3KeD_6KFnSfoaqI"]}') assert reg.getAnc(dgkey) == ( b'0AAAAAAAAAAAAAAAAAAAAAAQE1NdOqtN0HlhBPc7-MHvsA4vajMwFYp2eIturQQo0stM' ) assert reg.getTel(snKey(pre=regk, sn=0)) is None assert reg.getTwe(snKey( pre=regk, sn=0)) == b'EjhsbizNCwN_EFuOxbUt8CN0xOctGRIVOW8X-XqA3fSk'