async def create_proof_request(conn): # 1. Init entities public_repo = PublicRepoInMemory() attr_repo = AttributeRepoInMemory() issuer = Issuer(IssuerWalletInMemory('issuer1', public_repo), attr_repo) # 2. Create a Schema schema = await issuer.genSchema('GVT', '1.0', GVT.attribNames()) schema_id = ID(schema.getKey()) # 3. Create keys for the Schema global global_dict await issuer.wallet.submitPublicKeys(schema_id, global_dict['public_key']) # 4. set attributes for user1 prover_id = 'BzfFCYk' attributes = GVT.attribs(name='Alex', age=28, height=175, sex='male') attr_repo.addAttributes(schema.getKey(), prover_id, attributes) verifier = Verifier(WalletInMemory('verifier1', public_repo)) proof_request = ProofRequest( name='Test_proof', version='1.0', nonce=verifier.generateNonce(), verifiableAttributes={ 'attr_uuid': AttributeInfo('name', schema.seqId)}, predicates={'predicate_uuid': PredicateGE('age', 18)}) global_dict['verifier'] = verifier global_dict['proof_request'] = proof_request conn.send(json.dumps(proof_request.to_str_dict()).encode())
async def testMultipledRevealed(prover1, allClaims, schemaGvtId, schemaXyzId, attrRepo, schemaGvt): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={ 'attr_uuid1': AttributeInfo(name='status'), 'attr_uuid2': AttributeInfo(name='name') }) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) claimsXyz = await prover1.wallet.getClaimSignature(schemaXyzId) proofClaims = { schemaGvt.seqId: ProofClaims(claimsGvt, ['name'], []), schemaGvt.seqId: ProofClaims(claimsXyz, ['status'], []) } attr1 = attrRepo.getAttributes(schemaXyzId.schemaKey, prover1.proverId)['status'] attr2 = attrRepo.getAttributes(schemaGvtId.schemaKey, prover1.proverId)['name'] requestedProof = RequestedProof( revealed_attrs={ 'attr_uuid1': [schemaGvt.seqId, attr1, str(encodeAttr(attr1))], 'attr_uuid2': [schemaGvt.seqId, attr2, str(encodeAttr(attr2))] }) assert proofClaims, requestedProof == await prover1._findClaims( proofRequest)
async def testRevealedAndPredicateDifferentIssuers(prover1, allClaims, schemaGvtId, schemaXyzId, attrRepo, schemaGvt): proofRequest = ProofRequest( "proof1", "1.0", 1, verifiableAttributes={'attr_uuid': AttributeInfo(name='status')}, predicates={'predicate_uuid': PredicateGE('age', 18)}) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) claimsXyz = await prover1.wallet.getClaimSignature(schemaXyzId) proofClaims = { schemaGvt.seqId: ProofClaims(claimsGvt, [], [PredicateGE('age', 18)]), schemaGvt.seqId: ProofClaims(claimsXyz, ['status'], []) } attr = attrRepo.getAttributes(schemaXyzId.schemaKey, prover1.proverId)['status'] requestedProof = RequestedProof( revealed_attrs={ 'attr_uuid': [schemaGvt.seqId, attr, str(encodeAttr(attr))] }, predicates={'predicate_uuid': schemaGvt.seqId}) assert proofClaims, requestedProof == await prover1._findClaims( proofRequest)
async def testNoPredicates(prover1, verifier, claimsProver1): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'uuid1': AttributeInfo( name='name'), 'uuid2': AttributeInfo(name='status')}, predicates={}) assert await presentProofAndVerify(verifier, proofRequest, prover1)
async def test_requested_proof_from_to_dict(prover1, nonce, claimsProver1Gvt): proofRequest = ProofRequest( "proof1", "1.0", 1, verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}, predicates={'predicate_uuid': PredicateGE('age', 18)}) proof = await prover1.presentProof(proofRequest) requested_proof_serialized = { 'revealed_attrs': { 'attr_uuid': ['1', 'Alex', '1139481716457488690172217916278103335'] }, 'predicates': { 'predicate_uuid': '1' }, 'self_attested_attrs': {}, 'unrevealed_attrs': {} } assert proof.requestedProof.to_str_dict() == requested_proof_serialized assert proof.requestedProof == RequestedProof.from_str_dict( requested_proof_serialized) assert proof.requestedProof == RequestedProof.from_str_dict( proof.requestedProof.to_str_dict())
async def testNoPredicates(prover1, prover2, verifier, allClaims): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid1': AttributeInfo(name='name'), 'attr_uuid2': AttributeInfo(name='name')}) assert await presentProofAndVerify(verifier, proofRequest, prover1) assert await presentProofAndVerify(verifier, proofRequest, prover2)
async def testGePredicate(prover1, prover2, verifier, allClaims): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid1': AttributeInfo(name='name')}, predicates={'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('period', 3)}) assert await presentProofAndVerify(verifier, proofRequest, prover1) assert await presentProofAndVerify(verifier, proofRequest, prover2)
async def testOneRevealedFromSpecificSchemaAndIssuer(prover1, allClaims, schemaGvt, schemaGvtId, attrRepo, keysGvt): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={ 'uuid': AttributeInfo( name='name', schema_seq_no=schemaGvt.seqId, issuer_did=schemaGvt.issuerId) }) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) proofClaims = {schemaGvt.seqId: ProofClaims(claimsGvt, ['name'], [])} attr = attrRepo.getAttributes(schemaGvtId.schemaKey, prover1.proverId)['name'] requestedProof = RequestedProof(revealed_attrs={ 'uuid': [str(schemaGvt.seqId), attr, str(encodeAttr(attr))] }) assert proofClaims, requestedProof == await prover1._findClaims( proofRequest) assert proofClaims, requestedProof == await prover1._findClaims( proofRequest)
def _merge_request(self, request_data): link_request = request_data.get('connection-request') linkName = link_request['name'] link = self.wallet.getConnection(linkName) request_proof_requests = request_data.get('proof-requests', None) if request_proof_requests: for icr in request_proof_requests: # match is found if name and version are same matchedProofRequest = next( (cr for cr in link.proofRequests if (cr.name == icr[NAME] and cr.version == icr[VERSION])), None) # if link.requestedProofs contains any claim request if matchedProofRequest: # merge 'attributes' and 'verifiableAttributes' matchedProofRequest.attributes = { **matchedProofRequest.attributes, **icr[ATTRIBUTES] } matchedProofRequest.verifiableAttributes = list( set(matchedProofRequest.verifiableAttributes).union( icr[VERIFIABLE_ATTRIBUTES])) else: # otherwise append proof request to link link.proofRequests.append( ProofRequest(icr[NAME], icr[VERSION], icr[ATTRIBUTES], icr[VERIFIABLE_ATTRIBUTES])) return link else: raise ConnectionAlreadyExists
async def testMultipleGePredicateNegative(prover1, verifier, claimsProver1): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}, predicates={'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('period', 9)}) with pytest.raises(ValueError): await presentProofAndVerify(verifier, proofRequest, prover1)
async def testOneRevealedFromOtherIssuer(prover1, allClaims, schemaGvt, schemaXyz): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={'uuid': AttributeInfo(name='name', schema_seq_no=schemaGvt.seqId, issuer_did=schemaXyz.issuerId)}) with pytest.raises(ValueError): await prover1._findClaims(proofRequest)
async def testMultipledPredicates(prover1, allClaims, schemaGvtId, schemaXyzId, schemaGvt): proofRequest = ProofRequest("proof1", "1.0", 1, predicates={ 'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('period', 8) }) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) claimsXyz = await prover1.wallet.getClaimSignature(schemaXyzId) proofClaims = { schemaGvt.seqId: ProofClaims(claimsGvt, [], [PredicateGE('age', 18)]), schemaGvt.seqId: ProofClaims(claimsXyz, [], [PredicateGE('period', 8)]) } requestedProof = RequestedProof(predicates={ 'predicate_uuid1': schemaGvt.seqId, 'predicate_uuid2': schemaGvt.seqId }) assert proofClaims, requestedProof == await prover1._findClaims( proofRequest)
async def verifyProof(self, msg: Any): body, (frm, _) = msg link = self.verifyAndGetLink(msg) if not link: raise NotImplementedError proof = body[PROOF_FIELD] proofRequest = ProofRequest.from_str_dict(body[PROOF_REQUEST_FIELD]) nonce = getNonceForProof(body[NONCE]) proofName = proofRequest.name proofs = {} for key, p in proof['proofs'].items(): schema = await self.verifier.wallet.getSchema( ID(schemaId=int(p['schema_seq_no']))) pk = await self.verifier.wallet.getPublicKey( ID(schemaKey=schema.getKey())) proofs[key] = ProofInfo.from_str_dict(p, str(pk.N)) proof = FullProof( proofs, AggregatedProof.from_str_dict(proof['aggregated_proof']), RequestedProof.from_str_dict(proof['requested_proof'])) result = await self.verifier.verify(proofRequest, proof) self.logger.info('Proof "{}" accepted with nonce {}'.format( proofName, nonce)) self.logger.info('Verifying proof "{}" from {}'.format( proofName, link.name)) status = 'verified' if result else 'failed verification' resp = { TYPE: PROOF_STATUS, DATA: ' Your Proof {} {} was received and {}\n'.format( proofRequest.name, proofRequest.version, status), } self.signAndSend(resp, link.localIdentifier, frm, origReqId=body.get(f.REQ_ID.nm)) if result: for uuid, attribute in proofRequest.verifiableAttributes.items(): # Log attributes that were verified self.logger.info('verified {}: {}'.format( attribute.name, proof.requestedProof.revealed_attrs[uuid][1])) self.logger.info( 'Verified that proof "{}" contains attributes ' 'from claim(s) issued by: {}'.format( proofName, ", ".join( sorted([v.issuer_did for k, v in proof.proofs.items()])))) await self._postProofVerif(proofName, link, frm) else: self.logger.info( 'Verification failed for proof {} from {} '.format( proofName, link.name))
async def testMultipleGePredicateMultipleRevealed(prover1, verifier, claimsProver1): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid1': AttributeInfo(name='name'), 'attr_uuid2': AttributeInfo(name='status')}, predicates={'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('period', 5)}) await presentProofAndVerify(verifier, proofRequest, prover1)
async def testNonceShouldBeSame(prover1, verifier, claimsProver1Gvt, nonce, genNonce): proofRequest = ProofRequest( "proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}) proof = await prover1.presentProof(proofRequest) proofRequest = ProofRequest( "proof1", "1.0", genNonce, verifiableAttributes=proofRequest.verifiableAttributes, predicates=proofRequest.predicates) assert not await verifier.verify(proofRequest, proof)
async def testEmpty(prover1): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={}, predicates={}) assert ({}, RequestedProof([], [], [], [])) == await prover1._findClaims(proofRequest)
async def testGePredicateForEqual(prover1, verifier, claimsProver1Gvt): proofRequest = ProofRequest( "proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}, predicates={'predicate_uuid': PredicateGE('age', 28)}) assert await presentProofAndVerify(verifier, proofRequest, prover1)
async def testClaimProofFromToDict(prover1, nonce, claimsProver1Gvt): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={ 'attr_uuid': AttributeInfo(name='name')}, predicates={'predicate_uuid': PredicateGE('age', 18)}) proof = await prover1.presentProof(proofRequest) assert proof == FullProof.fromStrDict(proof.toStrDict())
async def testGePredicateNegativeForBoth(prover1, prover2, verifier, allClaims): proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid1': AttributeInfo(name='name')}, predicates={'predicate_uuid1': PredicateGE('age', 38), 'predicate_uuid2': PredicateGE('period', 30)}) with pytest.raises(ValueError): await presentProofAndVerify(verifier, proofRequest, prover1) with pytest.raises(ValueError): await presentProofAndVerify(verifier, proofRequest, prover2)
async def testAttrNotFound(prover1, allClaims): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={ 'attr_uuid1': AttributeInfo(name='name'), 'attr_uuid2': AttributeInfo(name='aaa') }) with pytest.raises(ValueError): await prover1._findClaims(proofRequest)
async def testPredicateNotFound(prover1, allClaims): proofRequest = ProofRequest("proof1", "1.0", 1, predicates={ 'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('aaaa', 8) }) with pytest.raises(ValueError): await prover1._findClaims(proofRequest)
async def testOnePredicateOnly(prover1, allClaims, schemaGvtId, schemaGvt): proofRequest = ProofRequest("proof1", "1.0", 1, predicates={'uuid': PredicateGE('age', 18)}) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) proofClaims = {schemaGvt.seqId: ProofClaims(claimsGvt, [], [PredicateGE('age', 18)])} requestedProof = RequestedProof(predicates={'uuid': schemaGvt.seqId}) assert proofClaims, requestedProof == await prover1._findClaims(proofRequest)
async def testRevocedWithUpdateWitness(schemaGvtId, issuerGvt, prover1, verifier, claimsProver1Gvt): await issuerGvt.revoke(schemaGvtId, 1) proofRequest = ProofRequest( "proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}) with pytest.raises(ValueError): await presentProofAndVerify(verifier, proofRequest, prover1)
def sendProofReq(self, link: Connection, proofReqSchemaKey): if self._proofRequestsSchema and (proofReqSchemaKey in self._proofRequestsSchema): proofRequest = self._proofRequestsSchema[proofReqSchemaKey] proofRequest = ProofRequest( proofRequest[NAME], proofRequest[VERSION], getNonceForProof(link.request_nonce), proofRequest[ATTRIBUTES], proofRequest[VERIFIABLE_ATTRIBUTES] if VERIFIABLE_ATTRIBUTES in proofRequest else [], proofRequest[PREDICATES] if PREDICATES in proofRequest else []) op = { TYPE: PROOF_REQUEST, PROOF_REQUEST_FIELD: proofRequest.to_str_dict() } self.signAndSendToLink(msg=op, linkName=link.name) else: return ERR_NO_PROOF_REQUEST_SCHEMA_FOUND
async def testMultipleGePredicate(prover1, verifier, claimsProver1Gvt): proofRequest = ProofRequest( "proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}, predicates={ 'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('height', 170) }) assert await presentProofAndVerify(verifier, proofRequest, prover1)
async def testPredicatesEmpty(prover1, allClaims, schemaGvtId, attrRepo, schemaGvt): proofRequest = ProofRequest("proof1", "1.0", 1, verifiableAttributes={'uuid': AttributeInfo(name='name')}, predicates={}) claimsGvt = await prover1.wallet.getClaimSignature(schemaGvtId) proofClaims = {schemaGvt.seqId: ProofClaims(claimsGvt, ['name'], [])} attr = attrRepo.getAttributes(schemaGvtId.schemaKey, prover1.proverId)['name'] requestedProof = RequestedProof(revealed_attrs={'uuid': [schemaGvt.seqId, attr, str(encodeAttr(attr))]}) assert proofClaims, requestedProof == await prover1._findClaims(proofRequest)
async def verifyProof(self, msg: Any): body, (frm, _) = msg link = self.verifyAndGetLink(msg) if not link: raise NotImplementedError proof = body[PROOF_FIELD] proofRequest = ProofRequest.from_str_dict(body[PROOF_REQUEST_FIELD]) nonce = getNonceForProof(body[NONCE]) proofName = proofRequest.name proofs = {} for key, p in proof['proofs'].items(): schema = await self.verifier.wallet.getSchema(ID(schemaId=int(p['schema_seq_no']))) pk = await self.verifier.wallet.getPublicKey(ID(schemaKey=schema.getKey())) proofs[key] = ProofInfo.from_str_dict(p, str(pk.N)) proof = FullProof( proofs, AggregatedProof.from_str_dict( proof['aggregated_proof']), RequestedProof.from_str_dict( proof['requested_proof'])) result = await self.verifier.verify(proofRequest, proof) self.logger.info('Proof "{}" accepted with nonce {}' .format(proofName, nonce)) self.logger.info('Verifying proof "{}" from {}' .format(proofName, link.name)) status = 'verified' if result else 'failed verification' resp = { TYPE: PROOF_STATUS, DATA: ' Your Proof {} {} was received and {}\n'. format(proofRequest.name, proofRequest.version, status), } self.signAndSend(resp, link.localIdentifier, frm, origReqId=body.get(f.REQ_ID.nm)) if result: for uuid, attribute in proofRequest.verifiableAttributes.items(): # Log attributes that were verified self.logger.info( 'verified {}: {}'. format( attribute.name, proof.requestedProof.revealed_attrs[uuid][1])) self.logger.info('Verified that proof "{}" contains attributes ' 'from claim(s) issued by: {}'.format( proofName, ", ".join( sorted([v.issuer_did for k, v in proof.proofs.items()])))) await self._postProofVerif(proofName, link, frm) else: self.logger.info('Verification failed for proof {} from {} ' .format(proofName, link.name))
async def testSingleIssuerMultipleCredDefsSingleProver(primes1, primes2): # 1. Init entities publicRepo = PublicRepoInMemory() attrRepo = AttributeRepoInMemory() issuer = Issuer(IssuerWalletInMemory('issuer1', publicRepo), attrRepo) # 2. Create a Schema schema1 = await issuer.genSchema('GVT', '1.0', GVT.attribNames()) schemaId1 = ID(schema1.getKey()) schema2 = await issuer.genSchema('XYZCorp', '1.0', XYZCorp.attribNames()) schemaId2 = ID(schema2.getKey()) # 3. Create keys for the Schema await issuer.genKeys(schemaId1, **primes1) await issuer.genKeys(schemaId2, **primes2) # 4. Issue accumulator await issuer.issueAccumulator(schemaId=schemaId1, iA='110', L=5) await issuer.issueAccumulator(schemaId=schemaId2, iA=9999999, L=5) # 4. set attributes for user1 userId = '111' attrs1 = GVT.attribs(name='Alex', age=28, height=175, sex='male') attrs2 = XYZCorp.attribs(status='FULL', period=8) attrRepo.addAttributes(schema1.getKey(), userId, attrs1) attrRepo.addAttributes(schema2.getKey(), userId, attrs2) # 5. request Claims prover = Prover(ProverWalletInMemory(userId, publicRepo)) claimsReqs = await prover.createClaimRequests([schemaId1, schemaId2]) claims = await issuer.issueClaims(claimsReqs) await prover.processClaims(claims) # 6. proof Claims verifier = Verifier(WalletInMemory('verifier1', publicRepo)) proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(), verifiableAttributes={ 'attr_uuid1': AttributeInfo('name', schema1.seqId) }, predicates={ 'predicate_uuid1': PredicateGE('age', 18), 'predicate_uuid2': PredicateGE('period', 5) }) proof = await prover.presentProof(proofRequest) assert proof.requestedProof.revealed_attrs['attr_uuid1'][1] == 'Alex' assert await verifier.verify(proofRequest, proof)
def test_proof_request_from_to_dict(): proofRequest = ProofRequest( "proof1", "1.0", 1, verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}, predicates={'predicate_uuid': PredicateGE('age', 18)}) proof_input_serialized = { 'name': 'proof1', 'version': '1.0', 'nonce': '1', 'requested_attrs': { 'attr_uuid': { 'name': 'name', 'schema_seq_no': None, 'issuer_did': None } }, 'requested_predicates': { 'predicate_uuid': { 'p_type': 'GE', 'value': 18, 'attr_name': 'age', 'schema_seq_no': None, 'issuer_did': None } } } assert proofRequest.to_str_dict() == proof_input_serialized assert proofRequest == ProofRequest.from_str_dict(proof_input_serialized) assert proofRequest == ProofRequest.from_str_dict( proofRequest.to_str_dict())
async def create_proof(): proofRequest = ProofRequest("proof1", "1.0", int(acme_proof_req.nonce), verifiableAttributes=acme_proof_req.verifiableAttributes, predicates=acme_proof_req.predicates) proof = await aliceAgent.prover.presentProof(proofRequest) msg = get_proof_libindy_msg( acme_link, acme_proof_req, proof, str(schema.seqId), schema.seqId) aliceAgent.signAndSendToLink(msg=msg, linkName=acme_link.name)
async def testRevocedWithoutUpdateWitness(schemaGvtId, issuerGvt, prover1, verifier, claimsProver1Gvt): proofRequest = ProofRequest( "proof1", "1.0", verifier.generateNonce(), verifiableAttributes={'attr_uuid': AttributeInfo(name='name')}) proof = await prover1.presentProof(proofRequest) await issuerGvt.revoke(schemaGvtId, 1) return await verifier.verify(proofRequest, proof)
def sendProofReq(self, link: Link, proofReqSchemaKey): if self._proofRequestsSchema and ( proofReqSchemaKey in self._proofRequestsSchema): proofRequest = self._proofRequestsSchema[proofReqSchemaKey] proofRequest = ProofRequest( proofRequest[NAME], proofRequest[VERSION], getNonceForProof(link.invitationNonce), proofRequest[ATTRIBUTES], proofRequest[VERIFIABLE_ATTRIBUTES] if VERIFIABLE_ATTRIBUTES in proofRequest else [], proofRequest[PREDICATES] if PREDICATES in proofRequest else [] ) op = { TYPE: PROOF_REQUEST, PROOF_REQUEST_FIELD: proofRequest.to_str_dict() } self.signAndSendToLink(msg=op, linkName=link.name) else: return ERR_NO_PROOF_REQUEST_SCHEMA_FOUND
async def sendProofAsync(self, link: Link, proofRequest: ProofRequest): # TODO _F_ this nonce should be from the Proof Request, not from an # invitation # TODO rename presentProof to buildProof or generateProof proof = await self.prover.presentProof(proofRequest) proof.requestedProof.self_attested_attrs.update(proofRequest.selfAttestedAttrs) op = { TYPE: PROOF, NONCE: link.invitationNonce, PROOF_FIELD: proof.to_str_dict(), PROOF_REQUEST_FIELD: proofRequest.to_str_dict() } self.signAndSendToLink(msg=op, linkName=link.name)
def handleProofRequest(self, msg): body, _ = msg link = self._getLinkByTarget(getCryptonym(body.get(IDENTIFIER))) proofRequest = body.get(PROOF_REQUEST_FIELD) proofRequest = ProofRequest.from_str_dict(proofRequest) proofReqExist = False for request in link.proofRequests: if request.name == proofRequest.name: proofReqExist = True break self.notifyMsgListener(' Proof request {} received from {}.\n' .format(proofRequest.name, link.name)) if not proofReqExist: link.proofRequests.append(proofRequest) else: self.notifyMsgListener(' Proof request {} already exist.\n' .format(proofRequest.name))