def build(req_id: str, my_did: str, my_vk: str, endpoint: str) -> Message: return Message({ '@type': DIDExchange.RESPONSE, '@id': str(uuid.uuid4()), '~thread': {Message.THREAD_ID: req_id, Message.SENDER_ORDER: 0}, 'connection': { 'did': my_did, 'did_doc': { "@context": "https://w3id.org/did/v1", "id": my_did, "publicKey": [{ "id": my_did + "#keys-1", "type": "Ed25519VerificationKey2018", "controller": my_did, "publicKeyBase58": my_vk }], "service": [{ "id": my_did + ";indy", "type": "IndyAgent", "recipientKeys": [my_vk], # "routingKeys": ["<example-agency-verkey>"], "serviceEndpoint": endpoint, }], } } })
async def pack(msg: Message, wallet: WalletConnection, their_ver_key, routing_keys: list, my_ver_key=None) -> bytes: if not routing_keys: raise RuntimeError('routing_keys must not be empty') payload = await wallet.pack_message( Serializer.serialize(msg).decode(RoutingMessage.ENC), their_ver_key, my_ver_key ) keys_map = {} for n in range(len(routing_keys)-1, 0, -1): # example: IF routing_keys = ['k1', 'k2', 'k3'] THEN n = [2,1] outer_key = routing_keys[n] inner_key = routing_keys[n-1] keys_map[outer_key] = inner_key keys_map[routing_keys[0]] = their_ver_key for outer_key in routing_keys: inner_key = keys_map[outer_key] forwarded = Message({ '@type': RoutingMessage.FORWARD, 'to': inner_key, 'msg': json.loads(payload.decode(RoutingMessage.ENC)) }) payload = await wallet.pack_message( Serializer.serialize(forwarded).decode(RoutingMessage.ENC), outer_key, ) return payload
async def handle(self, content_type, data): try: if content_type == DIDExchange.MESSAGE_CONTENT_TYPE: kwargs = json.loads(data) msg = Message(**kwargs) elif content_type in WIRED_CONTENT_TYPES: msg = await DIDExchange.unpack_agent_message(data, self.get_wallet()) else: raise RuntimeError('Unknown content_type "%s"' % content_type) await self.__log('Receive', msg.to_dict()) if msg.type == DIDExchange.INVITE: await self.__receive_invitation(msg) elif msg.type == DIDExchange.RESPONSE: await self.__receive_connection_response(msg) elif msg.type == DIDExchange.PROBLEM_REPORT: if self.status == DIDExchangeStatus.Requested: # Stay in same state - retryable pass else: raise ImpossibleStatus() else: logging.error('Unexpected message type: %s' % msg.type) except Exception as e: if not isinstance(e, MachineIsDone): logging.exception('Base machine terminated with exception') await self.done()
def build(comment: str = None, response_requested: bool = True): creation = {'@type': TrustPing.PING, '@id': str(uuid.uuid4())} if comment: creation['comment'] = comment if response_requested in [True, False]: creation['response_requested'] = response_requested return Message(creation)
async def handle(cls, agent_name: str, wire_message: bytes, my_label: str = None, my_endpoint: str = None) -> bool: unpacked = await WalletAgent.unpack_message(agent_name, wire_message) kwargs = json.loads(unpacked['message']) message = Message(**kwargs) print('***** feature 0037 handle message *****') if 'sender_verkey' in unpacked: sender_verkey = unpacked['sender_verkey'] else: sender_verkey = None if 'recipient_verkey' in unpacked: recipient_verkey = unpacked['recipient_verkey'] else: recipient_verkey = None print('sender_verkey: ' + sender_verkey) print('recipient_verkey: ' + recipient_verkey) print(json.dumps(message.to_dict(), indent=2, sort_keys=True)) print('***************************************') if message.get('@type', None) is None: return False if not cls.endorsement(message): return False state_machine_id = cls.get_state_machine_id(unpacked['sender_verkey']) if message.type in [ PresentProofProtocol.REQUEST_PRESENTATION, AckMessage.ACK ]: if message.type == PresentProofProtocol.REQUEST_PRESENTATION: machine_class = PresentProofProtocol.ProverStateMachine await WalletAgent.start_state_machine( status=PresentProofStatus.Null, ttl=PresentProofProtocol.STATE_MACHINE_TTL, agent_name=agent_name, machine_class=machine_class, machine_id=state_machine_id) await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message) return True elif message.type in [PresentProofProtocol.PRESENTATION]: await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message) return True elif message.type == PresentProofProtocol.PROBLEM_REPORT: await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message) return True else: return False
def build(ping_id: str): return Message({ '@type': TrustPing.PING_RESPONSE, '~thread': { Message.THREAD_ID: ping_id, Message.SENDER_ORDER: 0 } })
def build_problem_report_for_connections(cls, problem_code, problem_str, thread_id: str=None) -> Message: initialized = { "@type": "{}/problem_report".format(cls.FAMILY), "problem-code": problem_code, "explain": problem_str } if thread_id: initialized['~thread'] = {Message.THREAD_ID: thread_id, Message.SENDER_ORDER: 0} return Message(initialized)
def build(thread_id: str, status: str="OK", sender_order: int=0) -> Message: return Message({ '@type': AckMessage.ACK, 'status': status, '~thread': { Message.THREAD_ID: thread_id, Message.SENDER_ORDER: sender_order } })
async def unpack(forwarded: Message, wallet: WalletConnection) -> (Message, str, str): RoutingMessage.validate(forwarded) forwarded_wired = json.dumps(forwarded['msg']).encode(RoutingMessage.ENC) unpacked = await wallet.unpack_message(forwarded_wired) kwargs = json.loads(unpacked['message']) forwarder = Message(**kwargs) sender_verkey = unpacked.get('sender_verkey', None) recipient_verkey = unpacked.get('recipient_verkey', None) return forwarder, recipient_verkey, sender_verkey
async def test_forwarding_message(): wallet1_name = 'test_wallet_1' wallet2_name = 'test_wallet_2' pass_phrase = 'pass_phrase' await remove_wallets(wallet1_name, wallet2_name) conn_sender = WalletConnection(wallet1_name, pass_phrase) conn_recipient = WalletConnection(wallet2_name, pass_phrase) await conn_sender.create() await conn_recipient.create() try: await conn_sender.open() await conn_recipient.open() # build expected message message = BasicMessage.build(content='Test content') # generate keys sender_verkey = await conn_sender.create_key() recipient_verkey = await conn_recipient.create_key() routing_key1 = await conn_recipient.create_key() routing_key2 = await conn_recipient.create_key() routing_keys = [routing_key1, routing_key2] print('-------- values ----------') print('sender_verkey: ' + sender_verkey) print('recipient_verkey: ' + recipient_verkey) print('routing_keys: ' + str(routing_keys)) print('--------------------------') # emulate communication wired = await RoutingMessage.pack(message, conn_sender, recipient_verkey, routing_keys, sender_verkey) unpacked = await conn_recipient.unpack_message(wired) kwargs = json.loads(unpacked['message']) message = Message(**kwargs) assert message.type == RoutingMessage.FORWARD assert unpacked.get('recipient_verkey') == routing_key2 assert unpacked.get('sender_verkey') is None assert message.data.get('to') == routing_key1 message, recipient_vk, sender_vk = await RoutingMessage.unpack( message, conn_recipient) assert message.type == RoutingMessage.FORWARD assert recipient_vk == routing_key1 assert sender_vk is None assert message.data.get('to') == recipient_verkey message, recipient_vk, sender_vk = await RoutingMessage.unpack( message, conn_recipient) assert message.type == BasicMessage.MESSAGE assert recipient_vk == recipient_verkey assert sender_vk == sender_verkey assert message.data.get('content') == 'Test content' finally: await conn_sender.delete() await conn_recipient.delete()
def build(content: str) -> Message: sent_time = datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat(' ') return Message({ '@type': BasicMessage.MESSAGE, '~l10n': { 'locale': 'en' }, 'sent_time': sent_time, 'content': content })
def propose_credential( cls, comment: str = None, locale: str = DEF_LOCALE, proposal_attrib: List[ProposedAttrib] = None, schema_id: str = None, schema_name: str = None, schema_version: str = None, schema_issuer_did: str = None, cred_def_id: str = None, issuer_did: str = None, proposal_attrib_translation: List[AttribTranslation] = None): data = { '@type': cls.PROPOSE_CREDENTIAL, '~l10n': { "locale": locale }, } if comment: data['comment'] = comment if schema_id: data['schema_id'] = schema_id if schema_name: data['schema_name'] = schema_name if schema_version: data['schema_version'] = schema_version if schema_issuer_did: data['schema_issuer_did'] = schema_issuer_did if cred_def_id: data['cred_def_id'] = cred_def_id if issuer_did: data['issuer_did'] = issuer_did if proposal_attrib: data['credential_proposal'] = { "@type": cls.CREDENTIAL_PREVIEW_TYPE, "attributes": [attrib.to_json() for attrib in proposal_attrib] } if proposal_attrib_translation: data['~attach'] = [{ "@type": cls.CREDENTIAL_TRANSLATION_TYPE, "id": cls.CREDENTIAL_TRANSLATION_ID, '~l10n': { "locale": locale }, "mime-type": "application/json", "data": { "json": [ trans.to_json() for trans in proposal_attrib_translation ] } }] return Message(data)
def build(label: str, connection_key: str, endpoint: str) -> str: msg = Message({ '@type': DIDExchange.INVITE, 'label': label, 'recipientKeys': [connection_key], 'serviceEndpoint': endpoint, # routing_keys not specified, but here is where they would be put in the invite. }) b64_invite = base64.urlsafe_b64encode( bytes( Serializer.serialize(msg).decode('utf-8'), 'ascii' ) ).decode('ascii') return '{}?c_i={}'.format(endpoint, b64_invite)
async def handle(cls, agent_name: str, wire_message: bytes, my_label: str = None, my_endpoint: str = None) -> bool: unpacked = await WalletAgent.unpack_message(agent_name, wire_message) kwargs = json.loads(unpacked['message']) message = Message(**kwargs) if message.get('@type', None) is None: return False if not cls.endorsement(message): return False for protocol_version in ["1.1", "1.0"]: type_issue_credential = cls.set_protocol_version( cls.ISSUE_CREDENTIAL, protocol_version) type_offer_credential = cls.set_protocol_version( cls.OFFER_CREDENTIAL, protocol_version) type_request_credential = cls.set_protocol_version( cls.REQUEST_CREDENTIAL, protocol_version) state_machine_id = cls.get_state_machine_id( unpacked['sender_verkey']) if message.type in [type_issue_credential, type_offer_credential]: machine_class = IssueCredentialProtocol.HolderSateMachine if message.type == type_offer_credential: await WalletAgent.start_state_machine( status=IssueCredentialStatus.Null, ttl=IssueCredentialProtocol.STATE_MACHINE_TTL, agent_name=agent_name, machine_class=machine_class, machine_id=state_machine_id, protocol_version=protocol_version) await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message) return True elif message.type in [type_request_credential, AckMessage.ACK]: await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message) return True return False
async def handle(cls, agent_name: str, wire_message: bytes, my_label: str=None, my_endpoint: str=None) -> bool: unpacked = await WalletAgent.unpack_message(agent_name, wire_message) kwargs = json.loads(unpacked['message']) message = Message(**kwargs) if message.get('@type', None) is None: return False if message.type == cls.REQUEST: state_machine_id = unpacked['sender_verkey'] machine_class = DIDExchange.DIDExchangeInviterStateMachine await WalletAgent.start_state_machine( agent_name=agent_name, machine_class=machine_class, machine_id=state_machine_id, endpoint=my_endpoint, label=my_label, status=DIDExchangeStatus.Invited ) await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message ) return True elif message.type == DIDExchange.RESPONSE: state_machine_id = message['connection~sig']['signer'] await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message ) return True elif message.type in [TrustPing.PING, TrustPing.PING_RESPONSE]: state_machine_id = unpacked['sender_verkey'] await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message ) return True elif message.type == DIDExchange.PROBLEM_REPORT: state_machine_id = message.to_dict().get('connection~sig', {}).get('signer') if state_machine_id: await WalletAgent.invoke_state_machine( agent_name=agent_name, id_=state_machine_id, content_type=cls.WIRED_CONTENT_TYPE, data=wire_message ) return True else: logging.error('Problem report', message.as_json()) return True else: return False
async def generate_invite_message(cls, label: str, endpoint: str, agent_name: str, pass_phrase: str, extra: dict=None) -> Message: """ Generate new connection invitation. This interaction represents an out-of-band communication channel. In the future and in practice, these sort of invitations will be received over any number of channels such as SMS, Email, QR Code, NFC, etc. Structure of an invite message: { "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", "label": "Alice", "did": "did:sov:QmWbsNYhMrjHiqZDTUTEJs" } Or, in the case of a peer DID: { "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", "label": "Alice", "did": "did:peer:oiSqsNYhMrjHiqZDTUthsw", "key": "8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K", "endpoint": "https://example.com/endpoint" } Currently, only peer DID is supported. """ await WalletAgent.ensure_agent_is_open(agent_name, pass_phrase) connection_key = await WalletAgent.create_key(agent_name, pass_phrase) # Store connection key # await WalletAgent.add_wallet_record(agent_name, pass_phrase, 'connection_key', connection_key, connection_key) data = { '@type': cls.INVITE, 'label': label, 'recipientKeys': [connection_key], 'serviceEndpoint': endpoint, # routingKeys not specified, but here is where they would be put in the invite. } if extra: data.update(extra) invite_msg = Message(data) return invite_msg
def main(): parser = argparse.ArgumentParser() parser.add_argument("--adj_nodes_path", help="Path to a list of ips of adjacent nodes", required=True, type=str) args = vars(parser.parse_args()) self_ip = get_my_ip() adj_nodes_path = args['adj_nodes_path'] adj_nodes_ips = None with open(adj_nodes_path, 'r') as f: adj_nodes_ips = f.read().splitlines() my_node = Node(self_ip, adj_nodes_ips) newstdin = os.fdopen(os.dup(sys.stdin.fileno())) manager = Manager() my_node.yet_to_submit = manager.dict() my_node.jobQ = manager.list() my_node.resources = manager.dict() my_node.job_pid = manager.dict() my_node.lost_resources = manager.dict() my_node.pids = manager.dict() my_node.leader_last_seen = manager.dict() my_node.log_q = manager.Queue() my_node.failed_msgs = manager.list() my_node.backup_state = manager.list() my_node.ip_dict = manager.dict() my_node.ip_dict['root'] = self_ip # my_node.backup_ip_dict = manager.dict() log_file = 'main_log_data.txt' logging_p = Process(target=start_logger, args=(my_node.log_q, log_file, "INFO")) logging_p.start() time.sleep(5) my_node.pids['logging'] = logging_p.pid interface_p = Process(target=submit_interface, args=(my_node, newstdin)) interface_p.start() my_node.submit_interface_pid = interface_p.pid # start receiving messages msg_socket = build_socket(self_ip) # Leader election initiate_leader_election(my_node) msg = Message() matchmaker_started = False while 1: conn, recv_addr = msg_socket.accept() recv_addr = recv_addr[0] msg = recv_msg(conn) ty = "INFO" # if 'HEARTBEAT' in msg.msg_type: # ty = "DEBUG" # print('received msg of type %s from %s' %(msg.msg_type, recv_addr)) add_log(my_node, 'received msg of type %s from %s' % (msg.msg_type, recv_addr), ty) if msg.msg_type == 'LE_QUERY': handlers.le_query_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'LE_ACCEPT': handlers.le_accept_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'LE_REJECT': handlers.le_reject_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'LE_TERMINATE': handlers.le_terminate_handler(my_node) elif msg.msg_type == 'BACKUP_QUERY': handlers.backup_query_handler(my_node) leader_crash_detector_p = Process(target=leader_crash_detect, args=(my_node, )) leader_crash_detector_p.start() my_node.pids['leader_crash_detector'] = leader_crash_detector_p.pid elif msg.msg_type == 'EXEC_JOB': handlers.exec_job_handler(my_node, msg.content) elif msg.msg_type == 'QUERY_FILES': handlers.query_files_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'HEARTBEAT': handlers.heartbeat_handler(my_node, recv_addr, msg.content, manager) elif msg.msg_type == 'FILES_CONTENT': handlers.files_content_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'ARE_YOU_ALIVE': handlers.send_heartbeat(my_node, recv_addr) elif msg.msg_type == 'HEARTBEAT_ACK': handlers.heartbeat_ack_handler(my_node) elif msg.msg_type == 'LOG_FILE': handlers.log_file_handler(my_node, msg.content) elif msg.msg_type == 'LOG_FILE_ACK': handlers.log_file_ack_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'COMPLETED_JOB': handlers.completed_job_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'PREEMPT_AND_EXEC': handlers.preempt_and_exec_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'PREEMPTED_JOB': handlers.preempted_job_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'STATUS_JOB': handlers.status_job_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'STATUS_REPLY': handlers.status_reply_handler(my_node, msg.content) elif msg.msg_type == 'GET_ALIVE_NODE': handlers.get_alive_node_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'GET_ALIVE_NODE_ACK': handlers.get_alive_node_ack_handler(my_node, msg.content) elif msg.msg_type == 'DISPLAY_OUTPUT': handlers.display_output_handler(my_node, recv_addr, msg.content) elif msg.msg_type == 'FWD_DISPLAY_OUTPUT': handlers.fwd_display_output_handler(my_node, msg.content) elif msg.msg_type == 'DISPLAY_OUTPUT_ACK': handlers.display_output_ack_handler(my_node, msg.content) elif msg.msg_type == 'FWD_DISPLAY_OUTPUT_ACK': handlers.fwd_display_output_ack_handler(my_node, msg.content) elif msg.msg_type == 'BACKUP_HEARTBEAT': handlers.backup_heartbeat_handler(my_node) elif msg.msg_type == 'BACKUP_HEARTBEAT_ACK': handlers.backup_heartbeat_ack_handler(my_node, msg.content) elif msg.msg_type == 'U_ARE_LEADER': my_node.running_jobs = manager.dict() my_node.leader_jobPQ = JobPQ(manager) my_node.last_heartbeat_ts = manager.dict() my_node.leader_joblist = manager.list() handlers.new_leader_handler(my_node, recv_addr, msg.content) matchmaker_p = Process(target=matchmaking, args=(my_node, )) matchmaker_p.start() matchmaker_started = True add_log(my_node, "Starting Matchmaker", ty="INFO") crash_detector_p = Process(target=crash_detect, args=(my_node, )) crash_detector_p.start() add_log(my_node, "Starting Crash Detector", ty="INFO") time.sleep(5) my_node.pids['matchmaker'] = matchmaker_p.pid my_node.pids['crash_detector'] = crash_detector_p.pid elif msg.msg_type == 'ELECT_NEW_LEADER': handlers.elect_new_leader_handler(my_node) elif msg.msg_type == 'I_AM_NEWLEADER': handlers.i_am_newleader_handler(my_node, recv_addr) elif msg.msg_type == 'LE_FORCE_LEADER': handlers.le_force_leader_handler(my_node, recv_addr, content) else: add_log(my_node, "Message of unexpected msg type" + msg.msg_type, ty="DEBUG") if my_node.le_elected and my_node.self_ip == my_node.ip_dict[ 'root'] and not matchmaker_started: my_node.running_jobs = manager.dict() my_node.leader_jobPQ = JobPQ(manager) my_node.last_heartbeat_ts = manager.dict() my_node.leader_joblist = manager.list() matchmaker_p = Process(target=matchmaking, args=(my_node, )) matchmaker_p.start() # time.sleep(5) add_log(my_node, "Starting Matchmaker", ty="INFO") matchmaker_started = True crash_detector_p = Process(target=crash_detect, args=(my_node, )) crash_detector_p.start() time.sleep(5) add_log(my_node, "Starting Crash Detector", ty="INFO") my_node.pids['matchmaker'] = matchmaker_p.pid my_node.pids['crash_detector'] = crash_detector_p.pid
async def handle(self, content_type, data): try: if content_type in WIRED_CONTENT_TYPES: msg, context = await PresentProofProtocol.unpack_agent_message( data, self.get_wallet()) self.to = context.their_did success, err_msg = await PresentProofProtocol.validate_common_message_blocks( msg, PresentProofProtocol.REQUEST_NOT_ACCEPTED, context) if not success and err_msg: await PresentProofProtocol.send_message_to_agent( context.their_did, err_msg, self.get_wallet()) else: raise RuntimeError('Unsupported content_type "%s"' % content_type) if msg.type == PresentProofProtocol.REQUEST_PRESENTATION: if self.status == PresentProofStatus.Null: await self.__log('Received request presentation', msg.to_dict()) request_attach = msg['request_presentations~attach'] if isinstance(request_attach, list): request_attach = request_attach[0] payload = json.loads( base64.b64decode( request_attach['data']['base64']).decode()) proof_request = payload search_handle = await self.get_wallet( ).prover_search_credentials_for_proof_req( proof_request=proof_request) try: requested_attributes = proof_request.get( 'requested_attributes', {}) requested_predicates = proof_request.get( 'requested_predicates', {}) schemas_json = dict() cred_defs_json = dict() prover_requested_creds = { 'self_attested_attributes': {}, 'requested_attributes': {}, 'requested_predicates': {} } for attr_referent in requested_attributes.keys(): cred_for_attr = await self.get_wallet( ).prover_fetch_credentials_for_proof_req( search_handle=search_handle, item_referent=attr_referent, count=1) if cred_for_attr: cred_info = cred_for_attr[0]['cred_info'] schema_id = cred_info['schema_id'] schemas_json[ schema_id] = await indy_sdk_utils.get_issuer_schema( self.get_wallet(), schema_id) cred_def_id = cred_info['cred_def_id'] cred_defs_json[ cred_def_id] = await indy_sdk_utils.get_cred_def( self.get_wallet(), cred_def_id) prover_requested_creds[ 'requested_attributes'][ attr_referent] = { 'cred_id': cred_info['referent'], 'revealed': True } for pred_referent in requested_predicates.keys(): cred_for_predicate = await self.get_wallet( ).prover_fetch_credentials_for_proof_req( search_handle=search_handle, item_referent=pred_referent, count=1) if cred_for_predicate: cred_info = cred_for_predicate[0][ 'cred_info'] schema_id = cred_info['schema_id'] schemas_json[ schema_id] = await indy_sdk_utils.get_issuer_schema( self.get_wallet(), schema_id) cred_def_id = cred_info['cred_def_id'] cred_defs_json[ cred_def_id] = await indy_sdk_utils.get_cred_def( self.get_wallet(), cred_def_id) prover_requested_creds[ 'requested_predicates'][ pred_referent] = { 'cred_id': cred_info['referent'], } finally: await self.get_wallet( ).prover_close_credentials_search_for_proof_req( search_handle) master_secret_name = settings.INDY['WALLET_SETTINGS'][ 'PROVER_MASTER_SECRET_NAME'] proof = await self.get_wallet().prover_create_proof( proof_req=proof_request, requested_creds=prover_requested_creds, link_secret_id=master_secret_name, schemas=schemas_json, cred_defs=cred_defs_json, rev_states=None) self.ack_message_id = uuid.uuid4().hex data = { "@type": PresentProofProtocol.PRESENTATION, "@id": self.ack_message_id, "presentations~attach": [{ "@id": "libindy-presentation-" + self.ack_message_id, "mime-type": "application/json", "data": { "base64": base64.b64encode( json.dumps(proof).encode()).decode() } }] } message_proof = Message(data) await PresentProofProtocol.send_message_to_agent( self.to, message_proof, self.get_wallet()) self.status = PresentProofStatus.PresentationSent await self.__log(event='Send Proof', details=data) else: await self.__send_problem_report( problem_code=PresentProofProtocol. REQUEST_PROCESSING_ERROR, problem_str='Impossible state machine state', context=context, thread_id=msg.id) raise ImpossibleStatus elif msg.type == AckMessage.ACK: await self.__log('Received ack', msg.to_dict()) if self.status == PresentProofStatus.PresentationSent: await self.done() else: await self.__send_problem_report( problem_code=PresentProofProtocol. RESPONSE_NOT_ACCEPTED, problem_str='UnExpected message type for status', context=context, thread_id=msg.id) raise ImpossibleStatus elif msg.type == PresentProofProtocol.PROBLEM_REPORT: await self.__log('Received problem report', msg.to_dict()) await self.done() else: await self.__send_problem_report( problem_code=PresentProofProtocol. RESPONSE_FOR_UNKNOWN_REQUEST, problem_str='Unknown message type', context=context, thread_id=msg.id) except Exception as e: if not isinstance(e, MachineIsDone): logging.exception('Base machine terminated with exception') await self.done()
async def handle(self, content_type, data): try: if content_type == PresentProofProtocol.MESSAGE_CONTENT_TYPE: command = str(data.get('command', None)) if command == PresentProofProtocol.CMD_START: await self.__log('Start verifying', data) # Store Context comment = data.get('comment', None) locale = data.get( 'locale', None) or PresentProofProtocol.DEF_LOCALE proof_request = data['proof_request'] self.proof_request_buffer = json.dumps(proof_request) translation = data.get('translation', None) translation = [ AttribTranslation(**item) for item in translation ] if translation else None id_suffix = uuid.uuid4().hex data = { "@type": PresentProofProtocol.REQUEST_PRESENTATION, "comment": "some comment", "request_presentations~attach": [{ "@id": "libindy-request-presentation-" + id_suffix, "mime-type": "application/json", "data": { "base64": base64.b64encode( json.dumps( proof_request).encode()).decode() } }] } if comment: data['comment'] = comment data['~l10n'] = {"locale": locale} self.comment = comment self.locale = locale if translation: data['~attach'] = [{ "@type": PresentProofProtocol. CREDENTIAL_TRANSLATION_TYPE, "id": PresentProofProtocol.CREDENTIAL_TRANSLATION_ID, '~l10n': { "locale": locale }, "mime-type": "application/json", "data": { "json": [trans.to_json() for trans in translation] } }] if self.expires_time: data['~timing'] = { "expires_time": self.expires_time } message_request = Message(data) await PresentProofProtocol.send_message_to_agent( self.to, message_request, self.get_wallet()) self.status = PresentProofStatus.RequestSent await self.__log(event='Send Request-Presentation', details=data) elif command == PresentProofProtocol.CMD_STOP: if self.to and self.status != PresentProofStatus.Null: err_msg = PresentProofProtocol.build_problem_report_for_connections( problem_code=PresentProofProtocol. REQUEST_NOT_ACCEPTED, problem_str='Actor unexpected stopped issuing', ) await PresentProofProtocol.send_message_to_agent( self.to, err_msg, self.get_wallet()) await self.__log('Actor unexpected stopped issuing') await self.done() else: raise RuntimeError('Unknown command: %s' % command) elif content_type in WIRED_CONTENT_TYPES: msg, context = await PresentProofProtocol.unpack_agent_message( data, self.get_wallet()) success, err_msg = await PresentProofProtocol.validate_common_message_blocks( msg, PresentProofProtocol.REQUEST_NOT_ACCEPTED, context) if not success and err_msg: await PresentProofProtocol.send_message_to_agent( context.their_did, err_msg, self.get_wallet()) if msg.type == PresentProofProtocol.PRESENTATION: await self.__log('Received presentation', msg.to_dict()) if self.status == PresentProofStatus.RequestSent: presentation_attach = msg['presentations~attach'] if isinstance(presentation_attach, list): presentation_attach = presentation_attach[0] payload = json.loads( base64.b64decode(presentation_attach['data'] ['base64']).decode()) proof = payload proof_request = json.loads( self.proof_request_buffer) await self.__log('verifier proof-request', proof_request) await self.__log(core.const.PROOF, proof) schemas = dict() cred_defs = dict() for ident in proof['identifiers']: schema_id = ident['schema_id'] cred_def_id = ident['cred_def_id'] schema = await indy_sdk_utils.get_issuer_schema( self.get_wallet(), schema_id ) or await get_issuer_schema(schema_id) if schema: schemas[schema_id] = schema else: _, schema = await core.ledger.get_schema( context.my_did, schema_id) schemas[schema_id] = schema cred_def = await indy_sdk_utils.get_cred_def( self.get_wallet(), cred_def_id ) or await get_cred_def_meta(cred_def_id) if cred_def: cred_defs[ cred_def_id] = self.__prepare_cred_def( cred_def) else: _, cred_def = await core.ledger.get_cred_def( context.my_did, cred_def_id) await indy_sdk_utils.store_cred_def( self.get_wallet(), cred_def_id, cred_def) cred_defs[ cred_def_id] = self.__prepare_cred_def( cred_def) await self.__log('schemas', schemas) await self.__log('cred_defs', cred_defs) success, error_message = await verifier_verify_proof( proof_request=proof_request, proof=proof, schemas=schemas, credential_defs=cred_defs, rev_reg_defs=None, rev_regs=None) await self.__log( 'verify result', dict(success=success, error_message=error_message)) if success: ack = AckMessage.build(msg.id) await PresentProofProtocol.send_message_to_agent( self.to, ack, self.get_wallet()) await self.__log(event='Send Ack', details=ack.to_dict()) await self.__log( event=core.const.VERIFY_SUCCESS) else: if error_message: if 'Invalid structure' in error_message: error_message = None await self.__send_problem_report( problem_code=PresentProofProtocol. VERIFY_ERROR, problem_str=error_message or 'Proof verification finished with errors', context=context, thread_id=msg.id) await self.__log(core.const.VERIFY_ERROR) await self.done() else: await self.__send_problem_report( problem_code=PresentProofProtocol. RESPONSE_NOT_ACCEPTED, problem_str='Impossible state', context=context, thread_id=msg.id) raise ImpossibleStatus() elif msg.type == PresentProofProtocol.PROBLEM_REPORT: await self.__log('Received problem report', msg.to_dict()) await self.done() else: await self.__send_problem_report( problem_code=PresentProofProtocol. RESPONSE_FOR_UNKNOWN_REQUEST, problem_str='Unknown message type', context=context, thread_id=msg.id) except Exception as e: if not isinstance(e, MachineIsDone): print('------------- FEATURE 0037 --------------') print('Exception') print(str(e)) print('----------------------------------------') logging.exception( 'Base machine terminated with exception: %s' % str(e)) await self.done()
async def handle(self, content_type, data): try: msg_type_offer_credential = IssueCredentialProtocol.set_protocol_version( IssueCredentialProtocol.OFFER_CREDENTIAL, self.protocol_version or IssueCredentialProtocol.VERSION) msg_type_issue_credential = IssueCredentialProtocol.set_protocol_version( IssueCredentialProtocol.ISSUE_CREDENTIAL, self.protocol_version or IssueCredentialProtocol.VERSION) if content_type in WIRED_CONTENT_TYPES: msg, context = await IssueCredentialProtocol.unpack_agent_message( data, self.get_wallet()) self.to = context.their_did success, err_msg = await IssueCredentialProtocol.validate_common_message_blocks( msg, IssueCredentialProtocol.REQUEST_NOT_ACCEPTED, context) if not success: if err_msg: await IssueCredentialProtocol.send_message_to_agent( context.their_did, err_msg, self.get_wallet()) else: raise RuntimeError('Unsupported content_type "%s"' % content_type) if msg.type == msg_type_offer_credential: if self.status == IssueCredentialStatus.Null: await self.__log('Received credential offer', msg.to_dict()) offer, offer_body, cred_def_body = await self.__validate_cred_offer( msg, context) self.cred_def_id = offer_body['cred_def_id'] link_secret_name = settings.INDY['WALLET_SETTINGS'][ 'PROVER_MASTER_SECRET_NAME'] try: await self.get_wallet( ).prover_create_master_secret(link_secret_name) except WalletOperationError as e: if 'duplicate' in e.error_message.lower(): # nothing to do pass else: raise e # Create Credential request self.cred_def_buffer = json.dumps(cred_def_body) cred_request, metadata = await self.get_wallet( ).prover_create_credential_req( prover_did=context.my_did, cred_offer=offer_body, cred_def=cred_def_body, master_secret_id=link_secret_name) await self.__log( 'Cred request artifacts', dict(cred_request=cred_request, metadata=metadata)) self.cred_metadata = json.dumps(metadata) # Build request data = { "@type": IssueCredentialProtocol.REQUEST_CREDENTIAL, "~thread": { Message.THREAD_ID: msg.id, Message.SENDER_ORDER: 0 }, "requests~attach": [ { "@id": uuid.uuid4().hex, "mime-type": "application/json", "data": { "base64": base64.b64encode( json.dumps(cred_request).encode()). decode() } }, ] } if self.comment: data['comment'] = self.comment message_request = Message(data) await IssueCredentialProtocol.send_message_to_agent( self.to, message_request, self.get_wallet()) await self.__log('Send credential request', message_request.to_dict()) self.status = IssueCredentialStatus.RequestCredential else: await self.__send_problem_report( problem_code=IssueCredentialProtocol. OFFER_PROCESSING_ERROR, problem_str='Impossible state machine state', context=context, thread_id=msg.id) raise ImpossibleStatus elif msg.type == msg_type_issue_credential: if self.status == IssueCredentialStatus.RequestCredential: await self.__log('Received Issue credential', msg.to_dict()) cred_attaches = msg.to_dict().get( 'credentials~attach', None) if isinstance(cred_attaches, dict): cred_attaches = [cred_attaches] for cred_attach in cred_attaches: cred_body = cred_attach.get('data').get('base64') cred_body = base64.b64decode(cred_body) cred_body = json.loads(cred_body.decode()) cred_def = json.loads(self.cred_def_buffer) cred_id = cred_attach.get('@id', None) # Store credential cred_older = await self.get_wallet( ).prover_get_credential(cred_id) if cred_older: # Delete older credential await self.get_wallet( ).prover_delete_credential(cred_id) cred_id = await self.get_wallet( ).prover_store_credential( cred_req_metadata=json.loads( self.cred_metadata), cred=cred_body, cred_def=cred_def, rev_reg_def=self.rev_reg_def, cred_id=cred_id) await self.__log( 'Store credential with id: %s' % str(cred_id), cred_body) ack_message_id = msg.to_dict().get( '~please_ack', {}).get('message_id', None) if not ack_message_id: ack_message_id = msg.id ack = AckMessage.build(ack_message_id) await IssueCredentialProtocol.send_message_to_agent( self.to, ack, self.get_wallet()) await self.__log('Send ACK', ack.to_dict()) await self.done() else: await self.__send_problem_report( problem_code=IssueCredentialProtocol. ISSUE_PROCESSING_ERROR, problem_str='Impossible state machine state', context=context, thread_id=msg.id) raise ImpossibleStatus elif msg.type == IssueCredentialProtocol.PROBLEM_REPORT: await self.__log('Received problem report', msg.to_dict()) await self.done() else: await self.__send_problem_report( problem_code=IssueCredentialProtocol. RESPONSE_FOR_UNKNOWN_REQUEST, problem_str='Unknown message type', context=context, thread_id=msg.id) except Exception as e: if not isinstance(e, MachineIsDone): logging.exception('Base machine terminated with exception') await self.done()
async def handle(self, content_type, data): try: if content_type == IssueCredentialProtocol.MESSAGE_CONTENT_TYPE: command = str(data.get('command', None)) if command == IssueCredentialProtocol.CMD_START: if self.status == IssueCredentialStatus.Null: # Store Context comment = data.get('comment', None) locale = data.get( 'locale', None) or IssueCredentialProtocol.DEF_LOCALE values = data.get('values') cred_def = data.get('cred_def') await update_cred_def_meta(cred_def['id'], cred_def) preview = data.get('preview', None) issuer_schema = data.get('issuer_schema', None) if issuer_schema: await update_issuer_schema( issuer_schema['id'], issuer_schema) preview = [ ProposedAttrib(**item) for item in preview ] if preview else None translation = data.get('translation', None) translation = [ AttribTranslation(**item) for item in translation ] if translation else None self.values_buffer = json.dumps(values) # Call Indy offer = await self.get_wallet( ).issuer_create_credential_offer(self.cred_def_id) self.cred_offer_buffer = json.dumps(offer) await self.__log(event='Build offer with Indy lib', details=offer) payload = dict(**offer, **cred_def) await self.__log(event='Payload', details=payload) # Build Aries message id_suffix = uuid.uuid4().hex data = { "@type": IssueCredentialProtocol.OFFER_CREDENTIAL, '~l10n': { "locale": locale }, "offers~attach": [{ "@id": 'libindy-cred-offer-' + id_suffix, "mime-type": "application/json", "data": { "base64": base64.b64encode( json.dumps( payload).encode()).decode() } }] } if comment: data['comment'] = comment data['~l10n'] = {"locale": locale} self.comment = comment self.locale = locale if preview: data["credential_preview"] = { "@type": IssueCredentialProtocol. CREDENTIAL_PREVIEW_TYPE, "attributes": [attrib.to_json() for attrib in preview] } if translation or issuer_schema: data['~attach'] = [] if translation: data['~attach'].append({ "@type": IssueCredentialProtocol. CREDENTIAL_TRANSLATION_TYPE, "id": IssueCredentialProtocol. CREDENTIAL_TRANSLATION_ID, '~l10n': { "locale": locale }, "mime-type": "application/json", "data": { "json": [ trans.to_json() for trans in translation ] } }) if issuer_schema: data['~attach'].append({ "@type": IssueCredentialProtocol. ISSUER_SCHEMA_TYPE, "id": IssueCredentialProtocol. ISSUER_SCHEMA_ID, "mime-type": "application/json", "data": { "json": issuer_schema } }) if self.expires_time: data['~timing'] = { "expires_time": self.expires_time } message_offer = Message(data) await IssueCredentialProtocol.send_message_to_agent( self.to, message_offer, self.get_wallet()) self.status = IssueCredentialStatus.OfferCredential await self.__log(event='Send Offer message', details=data) else: raise RuntimeError('Unexpected command %s' % command) elif command == IssueCredentialProtocol.CMD_STOP: if self.to and self.status != IssueCredentialStatus.Null: err_msg = IssueCredentialProtocol.build_problem_report_for_connections( problem_code=IssueCredentialProtocol. ISSUE_PROCESSING_ERROR, problem_str='Actor unexpected stopped issuing', ) await IssueCredentialProtocol.send_message_to_agent( self.to, err_msg, self.get_wallet()) await self.__log('Actor unexpected stopped issuing') await self.done() else: raise RuntimeError('Unknown command: %s' % command) elif content_type in WIRED_CONTENT_TYPES: msg, context = await IssueCredentialProtocol.unpack_agent_message( data, self.get_wallet()) success, err_msg = await IssueCredentialProtocol.validate_common_message_blocks( msg, IssueCredentialProtocol.REQUEST_NOT_ACCEPTED, context) if not success: if err_msg: await IssueCredentialProtocol.send_message_to_agent( context.their_did, err_msg, self.get_wallet()) if msg.type == IssueCredentialProtocol.REQUEST_CREDENTIAL: if self.status == IssueCredentialStatus.OfferCredential: await self.__log('Received credential request', msg.to_dict()) # Issue credential cred_offer = json.loads(self.cred_offer_buffer) cred_request = msg.to_dict().get( 'requests~attach', None) cred_values = json.loads(self.values_buffer) encoded_cred_values = dict() for key, value in cred_values.items(): encoded_cred_values[key] = dict( raw=str(value), encoded=core.codec.encode(value)) if cred_request: if isinstance(cred_request, list): cred_request = cred_request[0] cred_request_body = cred_request.get( 'data').get('base64') cred_request_body = base64.b64decode( cred_request_body) cred_request_body = json.loads( cred_request_body.decode()) ret = await self.get_wallet( ).issuer_create_credential( cred_offer=cred_offer, cred_req=cred_request_body, cred_values=encoded_cred_values, rev_reg_id=self.rev_reg_id, blob_storage_reader_handle=self. blob_storage_reader_handle) cred, cred_revoc_id, revoc_reg_delta = ret await self.__log( 'Issue Credentials atrifacts', dict(cred=cred, cred_revoc_id=cred_revoc_id, revoc_reg_delta=revoc_reg_delta)) if self.cred_id: message_id = self.cred_id else: message_id = 'libindy-cred-' + uuid.uuid4( ).hex data = { "@type": IssueCredentialProtocol.ISSUE_CREDENTIAL, "~please_ack": { "message_id": message_id }, "credentials~attach": [{ "@id": message_id, "mime-type": "application/json", "~thread": { Message.THREAD_ID: msg.id, Message.SENDER_ORDER: 0 }, "data": { "base64": base64.b64encode( json.dumps( cred).encode()).decode() } }] } self.ack_message_id = message_id if self.comment: data['comment'] = self.commentcomment data['~l10n'] = {"locale": self.locale} issue_message = Message(data) await IssueCredentialProtocol.send_message_to_agent( self.to, issue_message, self.get_wallet()) self.status = IssueCredentialStatus.IssueCredential await self.__log(event='Issue credential', details=data) else: await self.__send_problem_report( problem_code=IssueCredentialProtocol. REQUEST_NOT_ACCEPTED, problem_str='Impossible state machine state', context=context, thread_id=msg.id) raise ImpossibleStatus elif msg.type == AckMessage.ACK: if self.status == IssueCredentialStatus.IssueCredential: await self.__log('Received ACK', msg.to_dict()) await self.done() else: """Nothing to do await self.__send_problem_report( problem_code=IssueCredentialProtocol.REQUEST_NOT_ACCEPTED, problem_str='Impossible state machine state', context=context, thread_id=msg.id ) raise ImpossibleStatus """ logging.warning('Impossible state machine state') elif msg.type == IssueCredentialProtocol.PROBLEM_REPORT: await self.__log('Received problem report', msg.to_dict()) await self.done() else: raise RuntimeError('Unsupported content_type "%s"' % content_type) except Exception as e: if not isinstance(e, MachineIsDone): logging.exception('Base machine terminated with exception') await self.done()
def deserialize(dump: bytes) -> Message: """ Deserialize from json string to Message, if it looks like a Message. Returns a dictionary otherwise. """ return Message(json.loads(dump))
def initiate_leader_election(my_node): msg = Message('LE_QUERY', content=my_node.self_ip) for ip in my_node.adj_nodes_ips: send_msg(msg, to=ip, my_node=my_node)