Ejemplo n.º 1
0
    def _handle_accept(self, msg: FipaMessage, dialogue: Dialogue) -> None:
        """
        Handle the ACCEPT.

        Respond with a MATCH_ACCEPT_W_INFORM which contains the address to send the funds to.

        :param msg: the message
        :param dialogue: the dialogue object
        :return: None
        """
        new_message_id = msg.message_id + 1
        new_target = msg.message_id
        self.context.logger.info("[{}]: received ACCEPT from sender={}".format(
            self.context.agent_name, msg.counterparty[-5:]))
        self.context.logger.info(
            "[{}]: sending MATCH_ACCEPT_W_INFORM to sender={}".format(
                self.context.agent_name, msg.counterparty[-5:]))
        proposal = cast(Description, dialogue.proposal)
        identifier = cast(str, proposal.values.get("ledger_id"))
        match_accept_msg = FipaMessage(
            message_id=new_message_id,
            dialogue_reference=dialogue.dialogue_label.dialogue_reference,
            target=new_target,
            performative=FipaMessage.Performative.MATCH_ACCEPT_W_INFORM,
            info={"address": self.context.agent_addresses[identifier]},
        )
        match_accept_msg.counterparty = msg.counterparty
        dialogue.update(match_accept_msg)
        self.context.outbox.put_message(
            to=msg.counterparty,
            sender=self.context.agent_address,
            protocol_id=FipaMessage.protocol_id,
            message=FipaSerializer().encode(match_accept_msg),
        )
        strategy = cast(Strategy, self.context.strategy)
        strategy.db.set_dialogue_status(
            str(dialogue.dialogue_label),
            msg.counterparty[-5:],
            "received_accept",
            "send_match_accept",
        )
Ejemplo n.º 2
0
    def _handle_inform(self, msg: FipaMessage, dialogue: Dialogue) -> None:
        """
        Handle the INFORM.

        If the INFORM message contains the transaction_digest then verify that it is settled, otherwise do nothing.
        If the transaction is settled send the car data, otherwise do nothing.

        :param msg: the message
        :param dialogue: the dialogue object
        :return: None
        """
        new_message_id = msg.message_id + 1
        new_target = msg.message_id
        self.context.logger.info("[{}]: received INFORM from sender={}".format(
            self.context.agent_name, msg.counterparty[-5:]))

        json_data = msg.info
        if "transaction_digest" in json_data.keys():
            is_valid = False
            tx_digest = json_data["transaction_digest"]
            self.context.logger.info(
                "[{}]: checking whether transaction={} has been received ...".
                format(self.context.agent_name, tx_digest))
            proposal = cast(Description, dialogue.proposal)
            ledger_id = cast(str, proposal.values.get("ledger_id"))
            total_price = cast(int, proposal.values.get("price"))
            not_settled = True
            time_elapsed = 0
            # TODO: fix blocking code; move into behaviour!
            while not_settled and time_elapsed < 60:
                is_valid = self.context.ledger_apis.is_tx_valid(
                    ledger_id,
                    tx_digest,
                    self.context.agent_addresses[ledger_id],
                    msg.counterparty,
                    cast(str, proposal.values.get("tx_nonce")),
                    cast(int, proposal.values.get("price")),
                )
                not_settled = not is_valid
                if not_settled:
                    time.sleep(2)
                    time_elapsed += 2
            if is_valid:
                token_balance = self.context.ledger_apis.token_balance(
                    ledger_id,
                    cast(str, self.context.agent_addresses.get(ledger_id)))

                strategy = cast(Strategy, self.context.strategy)
                strategy.record_balance(token_balance)

                self.context.logger.info(
                    "[{}]: transaction={} settled, new balance={}. Sending data to sender={}"
                    .format(
                        self.context.agent_name,
                        tx_digest,
                        token_balance,
                        msg.counterparty[-5:],
                    ))
                inform_msg = FipaMessage(
                    message_id=new_message_id,
                    dialogue_reference=dialogue.dialogue_label.
                    dialogue_reference,
                    target=new_target,
                    performative=FipaMessage.Performative.INFORM,
                    info=dialogue.carpark_data,
                )
                inform_msg.counterparty = msg.counterparty
                dialogue.update(inform_msg)
                self.context.outbox.put_message(
                    to=msg.counterparty,
                    sender=self.context.agent_address,
                    protocol_id=FipaMessage.protocol_id,
                    message=FipaSerializer().encode(inform_msg),
                )
                # dialogues = cast(Dialogues, self.context.dialogues)
                # dialogues.dialogue_stats.add_dialogue_endstate(Dialogue.EndState.SUCCESSFUL, dialogue.is_self_initiated)
                strategy.db.add_in_progress_transaction(
                    tx_digest,
                    msg.counterparty[-5:],
                    self.context.agent_name,
                    total_price,
                )
                strategy.db.set_transaction_complete(tx_digest)
                strategy.db.set_dialogue_status(
                    str(dialogue.dialogue_label),
                    msg.counterparty[-5:],
                    "transaction_complete",
                    "send_request_data",
                )
            else:
                self.context.logger.info(
                    "[{}]: transaction={} not settled, aborting".format(
                        self.context.agent_name, tx_digest))
        else:
            self.context.logger.info(
                "[{}]: did not receive transaction digest from sender={}.".
                format(self.context.agent_name, msg.counterparty[-5:]))
Ejemplo n.º 3
0
    def _handle_cfp(self, msg: FipaMessage, dialogue: Dialogue) -> None:
        """
        Handle the CFP.

        If the CFP matches the supplied services then send a PROPOSE, otherwise send a DECLINE.

        :param msg: the message
        :param dialogue: the dialogue object
        :return: None
        """
        new_message_id = msg.message_id + 1
        new_target = msg.message_id
        self.context.logger.info("[{}]: received CFP from sender={}".format(
            self.context.agent_name, msg.counterparty[-5:]))
        query = cast(Query, msg.query)
        strategy = cast(Strategy, self.context.strategy)

        if strategy.is_matching_supply(query) and strategy.has_data():
            proposal, carpark_data = strategy.generate_proposal_and_data(
                query, msg.counterparty)
            dialogue.carpark_data = carpark_data
            dialogue.proposal = proposal
            self.context.logger.info(
                "[{}]: sending a PROPOSE with proposal={} to sender={}".format(
                    self.context.agent_name, proposal.values,
                    msg.counterparty[-5:]))
            proposal_msg = FipaMessage(
                message_id=new_message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                target=new_target,
                performative=FipaMessage.Performative.PROPOSE,
                proposal=proposal,
            )
            proposal_msg.counterparty = msg.counterparty
            dialogue.update(proposal_msg)
            self.context.outbox.put_message(
                to=msg.counterparty,
                sender=self.context.agent_address,
                protocol_id=FipaMessage.protocol_id,
                message=FipaSerializer().encode(proposal_msg),
            )

            strategy.db.set_dialogue_status(
                str(dialogue.dialogue_label),
                msg.counterparty[-5:],
                "received_cfp",
                "send_proposal",
            )

        else:
            self.context.logger.info(
                "[{}]: declined the CFP from sender={}".format(
                    self.context.agent_name, msg.counterparty[-5:]))
            decline_msg = FipaMessage(
                message_id=new_message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                target=new_target,
                performative=FipaMessage.Performative.DECLINE,
            )
            decline_msg.counterparty = msg.counterparty
            dialogue.update(decline_msg)
            self.context.outbox.put_message(
                to=msg.counterparty,
                sender=self.context.agent_address,
                protocol_id=FipaMessage.protocol_id,
                message=FipaSerializer().encode(decline_msg),
            )

            strategy.db.set_dialogue_status(
                str(dialogue.dialogue_label),
                msg.counterparty[-5:],
                "received_cfp",
                "send_no_proposal",
            )