def handle(self, message: Message, sender: str) -> None: """ Implement the reaction to a message. :param message: the message :param sender: the sender :return: None """ tx_msg_response = cast(TransactionMessage, message) if tx_msg_response is not None and \ TransactionMessage.Performative(tx_msg_response.get("performative")) == TransactionMessage.Performative.ACCEPT: logger.info("[{}]: transaction was successful.".format(self.context.agent_name)) json_data = {'transaction_digest': tx_msg_response.get("transaction_digest")} dialogue_label = DialogueLabel.from_json(cast(Dict[str, str], tx_msg_response.get("dialogue_label"))) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] fipa_msg = cast(FIPAMessage, dialogue.last_incoming_message) new_message_id = cast(int, fipa_msg.get("message_id")) + 1 new_target_id = cast(int, fipa_msg.get("target")) + 1 counterparty_pbk = dialogue.dialogue_label.dialogue_opponent_pbk inform_msg = FIPAMessage(message_id=new_message_id, dialogue_reference=dialogue.dialogue_label.dialogue_reference, target=new_target_id, performative=FIPAMessage.Performative.INFORM, json_data=json_data) dialogue.outgoing_extend(inform_msg) self.context.outbox.put_message(to=counterparty_pbk, sender=self.context.agent_public_key, protocol_id=FIPAMessage.protocol_id, message=FIPASerializer().encode(inform_msg)) logger.info("[{}]: informing counterparty={} of transaction digest.".format(self.context.agent_name, counterparty_pbk[-5:])) self._received_tx_message = True else: logger.info("[{}]: transaction was not successful.".format(self.context.agent_name))
def test_dialogue_label(self): """Test the dialogue_label.""" assert self.dialogue_label.dialogue_starter_reference == str(0) assert self.dialogue_label.dialogue_responder_reference == "" assert self.dialogue_label.dialogue_opponent_addr == "opponent" assert self.dialogue_label.dialogue_starter_addr == "starter" assert str(self.dialogue_label) == "{}_{}_{}_{}".format( self.dialogue_label.dialogue_starter_reference, self.dialogue_label.dialogue_responder_reference, self.dialogue_label.dialogue_opponent_addr, self.dialogue_label.dialogue_starter_addr, ) dialogue_label2 = DialogueLabel( dialogue_reference=(str(0), ""), dialogue_opponent_addr="opponent", dialogue_starter_addr="starter", ) assert dialogue_label2 == self.dialogue_label dialogue_label3 = "This is a test" assert not dialogue_label3 == self.dialogue_label assert hash(self.dialogue_label) == hash(self.dialogue.dialogue_label) assert self.dialogue_label.json == dict( dialogue_starter_reference=str(0), dialogue_responder_reference="", dialogue_opponent_addr="opponent", dialogue_starter_addr="starter", ) assert DialogueLabel.from_json( self.dialogue_label.json) == self.dialogue_label
def test_dialogue_label(self): """Test the dialogue_label.""" assert self.dialogue_label.dialogue_starter_reference == str(0) assert self.dialogue_label.dialogue_responder_reference == '' assert self.dialogue_label.dialogue_opponent_pbk == "opponent" assert self.dialogue_label.dialogue_starter_pbk == "starter" dialogue_label2 = DialogueLabel(dialogue_reference=(str(0), ''), dialogue_opponent_pbk="opponent", dialogue_starter_pbk="starter") assert dialogue_label2 == self.dialogue_label dialogue_label3 = "This is a test" assert not dialogue_label3 == self.dialogue_label assert hash(self.dialogue_label) == hash(self.dialogue.dialogue_label) assert self.dialogue_label.json == dict( dialogue_starter_reference=str(0), dialogue_responder_reference='', dialogue_opponent_pbk="opponent", dialogue_starter_pbk="starter") assert DialogueLabel.from_json( self.dialogue_label.json) == self.dialogue_label
def handle(self, message: Message) -> None: """ Dispatch message to relevant handler and respond. :param message: the message :return: None """ tx_message = cast(TransactionMessage, message) if (tx_message.performative == TransactionMessage.Performative.SUCCESSFUL_SIGNING): self.context.logger.info( "[{}]: transaction confirmed by decision maker".format( self.context.agent_name)) info = tx_message.info dialogue_label = DialogueLabel.from_json( cast(Dict[str, str], info.get("dialogue_label"))) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] fipa_message = cast(FipaMessage, dialogue.last_incoming_message) if (fipa_message is not None and fipa_message.performative == FipaMessage.Performative.ACCEPT): self.context.logger.info( "[{}]: sending match accept to {}.".format( self.context.agent_name, dialogue.dialogue_label.dialogue_opponent_addr[-5:], )) fipa_msg = FipaMessage( performative=FipaMessage.Performative. MATCH_ACCEPT_W_INFORM, message_id=fipa_message.message_id + 1, dialogue_reference=dialogue.dialogue_label. dialogue_reference, target=fipa_message.message_id, info={ "tx_signature": tx_message.signed_payload.get("tx_signature"), "tx_id": tx_message.tx_id, }, ) dialogue.outgoing_extend(fipa_msg) self.context.outbox.put_message( to=dialogue.dialogue_label.dialogue_opponent_addr, sender=self.context.agent_address, protocol_id=FipaMessage.protocol_id, message=FipaSerializer().encode(fipa_msg), ) else: self.context.logger.warning( "[{}]: last message should be of performative accept.". format(self.context.agent_name)) else: self.context.logger.info( "[{}]: transaction was not successful.".format( self.context.agent_name))
def handle(self, message: Message) -> None: """ Implement the reaction to a message. :param message: the message :return: None """ tx_msg_response = cast(TransactionMessage, message) if ( tx_msg_response is not None and tx_msg_response.performative == TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT ): self.context.logger.info( "[{}]: transaction was successful.".format(self.context.agent_name) ) json_data = {"transaction_digest": tx_msg_response.tx_digest} info = tx_msg_response.info dialogue_label = DialogueLabel.from_json( cast(Dict[str, str], info.get("dialogue_label")) ) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] fipa_msg = cast(FipaMessage, dialogue.last_incoming_message) new_message_id = fipa_msg.message_id + 1 new_target_id = fipa_msg.message_id counterparty_id = dialogue.dialogue_label.dialogue_opponent_addr inform_msg = FipaMessage( message_id=new_message_id, dialogue_reference=dialogue.dialogue_label.dialogue_reference, target=new_target_id, performative=FipaMessage.Performative.INFORM, info=json_data, ) dialogue.outgoing_extend(inform_msg) self.context.outbox.put_message( to=counterparty_id, sender=self.context.agent_address, protocol_id=FipaMessage.protocol_id, message=FipaSerializer().encode(inform_msg), ) self.context.logger.info( "[{}]: informing counterparty={} of transaction digest.".format( self.context.agent_name, counterparty_id[-5:] ) ) self._received_tx_message = True else: self.context.logger.info( "[{}]: transaction was not successful.".format(self.context.agent_name) )
def handle(self, message: Message) -> None: """ Implement the reaction to a message. :param message: the message :return: None """ tx_msg_response = cast(TransactionMessage, message) if ( tx_msg_response.performative == TransactionMessage.Performative.SUCCESSFUL_SIGNING and ( tx_msg_response.tx_id == ERC1155Contract.Performative.CONTRACT_SIGN_HASH_SINGLE.value ) ): tx_signature = tx_msg_response.signed_payload.get("tx_signature") dialogue_label = DialogueLabel.from_json( cast(Dict[str, str], tx_msg_response.info.get("dialogue_label")) ) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] fipa_msg = cast(FipaMessage, dialogue.last_incoming_message) new_message_id = fipa_msg.message_id + 1 new_target = fipa_msg.message_id counterparty_addr = dialogue.dialogue_label.dialogue_opponent_addr inform_msg = FipaMessage( message_id=new_message_id, dialogue_reference=dialogue.dialogue_label.dialogue_reference, target=new_target, performative=FipaMessage.Performative.ACCEPT_W_INFORM, info={"tx_signature": tx_signature}, ) self.context.logger.info( "[{}]: sending ACCEPT_W_INFORM to agent={}: tx_signature={}".format( self.context.agent_name, counterparty_addr[-5:], tx_signature ) ) self.context.outbox.put_message( to=counterparty_addr, sender=self.context.agent_address, protocol_id=FipaMessage.protocol_id, message=FipaSerializer().encode(inform_msg), ) else: self.context.logger.info( "[{}]: signing failed: tx_msg_response={}".format( self.context.agent_name, tx_msg_response ) )
def handle(self, message: Message, sender: str) -> None: """ Dispatch message to relevant handler and respond. :param message: the message :param sender: the sender :return: None """ tx_message = cast(TransactionMessage, message) if TransactionMessage.Performative(tx_message.get( "performative")) == TransactionMessage.Performative.ACCEPT: logger.info( "[{}]: transaction confirmed by decision maker, sending match accept." .format(self.context.agent_name)) dialogue_label = DialogueLabel.from_json( cast(Dict[str, str], tx_message.get("dialogue_label"))) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] tac_message = dialogue.last_incoming_message if tac_message is not None and tac_message.get( "performative") == FIPAMessage.Performative.ACCEPT: fipa_msg = FIPAMessage( performative=FIPAMessage.Performative. MATCH_ACCEPT_W_ADDRESS, message_id=cast(int, tac_message.get("message_id")) + 1, dialogue_reference=dialogue.dialogue_label. dialogue_reference, target=tac_message.get("message_id"), address=tx_message.get("transaction_digest")) dialogue.outgoing_extend(fipa_msg) self.context.outbox.put_message( to=dialogue.dialogue_label.dialogue_opponent_pbk, sender=self.context.agent_public_key, protocol_id=FIPAMessage.protocol_id, message=FIPASerializer().encode(fipa_msg)) else: logger.info( "[{}]: last message should be of performative accept.". format(self.context.agent_name)) else: logger.info("[{}]: transaction was not successful.".format( self.context.agent_name))
def handle(self, message: Message) -> None: """ Dispatch message to relevant handler and respond. :param message: the message :return: None """ tx_message = cast(SigningMessage, message) if tx_message.performative == SigningMessage.Performative.SIGNED_MESSAGE: self.context.logger.info( "[{}]: transaction confirmed by decision maker".format( self.context.agent_name)) strategy = cast(Strategy, self.context.strategy) dialogue_label = DialogueLabel.from_json( cast(Dict[str, str], tx_message.skill_callback_info.get("dialogue_label"))) dialogues = cast(Dialogues, self.context.dialogues) dialogue = dialogues.dialogues[dialogue_label] last_fipa_message = cast(FipaMessage, dialogue.last_incoming_message) if (last_fipa_message is not None and last_fipa_message.performative == FipaMessage.Performative.ACCEPT): self.context.logger.info( "[{}]: sending match accept to {}.".format( self.context.agent_name, dialogue.dialogue_label.dialogue_opponent_addr[-5:], )) fipa_msg = FipaMessage( performative=FipaMessage.Performative. MATCH_ACCEPT_W_INFORM, message_id=last_fipa_message.message_id + 1, dialogue_reference=dialogue.dialogue_label. dialogue_reference, target=last_fipa_message.message_id, info={ "tx_signature": tx_message.signed_transaction, "tx_id": tx_message.dialogue_reference[0], }, ) fipa_msg.counterparty = dialogue.dialogue_label.dialogue_opponent_addr dialogue.update(fipa_msg) self.context.outbox.put_message(message=fipa_msg) elif (last_fipa_message is not None and last_fipa_message.performative == FipaMessage.Performative.MATCH_ACCEPT_W_INFORM and strategy.is_contract_tx): self.context.logger.info( "[{}]: sending atomic swap tx to ledger.".format( self.context.agent_name)) tx_signed = tx_message.signed_transaction tx_digest = self.context.ledger_apis.get_api( strategy.ledger_id).send_signed_transaction( tx_signed=tx_signed) # TODO; handle case when no tx_digest returned and remove loop assert tx_digest is not None, "Error when submitting tx." self.context.logger.info("[{}]: tx_digest={}.".format( self.context.agent_name, tx_digest)) count = 0 while (not self.context.ledger_apis.get_api( strategy.ledger_id).is_transaction_settled(tx_digest) and count < 20): self.context.logger.info( "[{}]: waiting for tx to confirm. Sleeping for 3 seconds ..." .format(self.context.agent_name)) time.sleep(3.0) count += 1 tx_receipt = self.context.ledger_apis.get_api( strategy.ledger_id).get_transaction_receipt( tx_digest=tx_digest) if tx_receipt is None: self.context.logger.info( "[{}]: Failed to get tx receipt for atomic swap.". format(self.context.agent_name)) elif tx_receipt.status != 1: self.context.logger.info( "[{}]: Failed to conduct atomic swap.".format( self.context.agent_name)) else: self.context.logger.info( "[{}]: Successfully conducted atomic swap. Transaction digest: {}" .format(self.context.agent_name, tx_digest)) # contract = cast(ERC1155Contract, self.context.contracts.erc1155) # result = contract.get_balances( # address=self.context.agent_address, # token_ids=[ # int(key) # for key in tx_message.terms.quantities_by_good_id.keys() # ] # + [ # int(key) # for key in tx_message.terms.amount_by_currency_id.keys() # ], # ) result = 0 self.context.logger.info( "[{}]: Current balances: {}".format( self.context.agent_name, result)) else: self.context.logger.warning( "[{}]: last message should be of performative accept or match accept." .format(self.context.agent_name)) else: self.context.logger.info( "[{}]: transaction was not successful.".format( self.context.agent_name))