Beispiel #1
0
    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))
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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))
Beispiel #5
0
    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)
            )
Beispiel #6
0
    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
                )
            )
Beispiel #7
0
    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))
Beispiel #8
0
    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))