Esempio n. 1
0
    def _handle_signed_transaction(self, signing_msg: SigningMessage,
                                   signing_dialogue: SigningDialogue) -> None:
        """
        Handle an oef search message.

        :param signing_msg: the signing message
        :param signing_dialogue: the dialogue
        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        if not strategy.is_contract_tx:
            self.context.logger.warning(
                "signed transaction handler only for contract case.")
            return None
        self.context.logger.info("transaction signed by decision maker.")
        dialogue_label = DialogueLabel.from_str(
            cast(str, signing_msg.skill_callback_info.get("dialogue_label")))
        fipa_dialogues = cast(FipaDialogues, self.context.fipa_dialogues)
        fipa_dialogue = fipa_dialogues.dialogues[dialogue_label]
        last_fipa_message = cast(FipaMessage,
                                 fipa_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(
                fipa_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=fipa_dialogue.dialogue_label.
                dialogue_reference,
                target=last_fipa_message.message_id,
                info={
                    "tx_signature": signing_msg.signed_transaction,
                    "tx_id": signing_msg.dialogue_reference[0],
                },
            )
            fipa_msg.counterparty = fipa_dialogue.dialogue_label.dialogue_opponent_addr
            fipa_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):
            self.context.logger.info("sending atomic swap tx to ledger.")
            tx_signed = signing_msg.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(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 ...")
                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.")
            elif tx_receipt.status != 1:
                self.context.logger.info("failed to conduct atomic swap.")
            else:
                self.context.logger.info(
                    "successfully conducted atomic swap. Transaction digest: {}"
                    .format(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(result))
        else:
            self.context.logger.warning(
                "last message should be of performative accept or match accept."
            )
Esempio n. 2
0
    def _handle_signed_message(self, signing_msg: SigningMessage,
                               signing_dialogue: SigningDialogue) -> None:
        """
        Handle an oef search message.

        :param signing_msg: the signing message
        :param signing_dialogue: the dialogue
        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        if strategy.is_contract_tx:
            self.context.logger.warning(
                "signed message handler only for non-contract case.")
            return None
        self.context.logger.info("message signed by decision maker.")
        dialogue_label = DialogueLabel.from_str(
            cast(str, signing_msg.skill_callback_info.get("dialogue_label")))
        fipa_dialogues = cast(FipaDialogues, self.context.fipa_dialogues)
        fipa_dialogue = fipa_dialogues.dialogues[dialogue_label]
        last_fipa_message = cast(FipaMessage,
                                 fipa_dialogue.last_incoming_message)
        if (last_fipa_message is not None and last_fipa_message.performative
                == FipaMessage.Performative.ACCEPT):
            fipa_msg = FipaMessage(
                performative=FipaMessage.Performative.MATCH_ACCEPT_W_INFORM,
                message_id=last_fipa_message.message_id + 1,
                dialogue_reference=fipa_dialogue.dialogue_label.
                dialogue_reference,
                target=last_fipa_message.message_id,
                info={"signature": signing_msg.signed_message.body},
            )
            fipa_msg.counterparty = last_fipa_message.counterparty
            fipa_dialogue.update(fipa_msg)
            self.context.outbox.put_message(message=fipa_msg)
            self.context.logger.info("sending match accept to {}.".format(
                fipa_dialogue.dialogue_label.dialogue_opponent_addr[-5:], ))
        elif (last_fipa_message is not None and last_fipa_message.performative
              == FipaMessage.Performative.MATCH_ACCEPT_W_INFORM):
            counterparty_signature = cast(
                str,
                signing_msg.skill_callback_info.get("counterparty_signature"))
            if counterparty_signature is not None:
                last_signing_msg = cast(Optional[SigningMessage],
                                        signing_dialogue.last_outgoing_message)
                assert (last_signing_msg
                        is not None), "Could not recover last signing message."
                tx_id = last_signing_msg.terms.sender_hash
                if "transactions" not in self.context.shared_state.keys():
                    self.context.shared_state["transactions"] = {}
                self.context.shared_state["transactions"][tx_id] = {
                    "terms": last_signing_msg.terms,
                    "sender_signature": signing_msg.signed_message.body,
                    "counterparty_signature": counterparty_signature,
                }
                self.context.logger.info("sending transaction to controller.")
            else:
                self.context.logger.warning(
                    "transaction has no counterparty signature!")
        else:
            self.context.logger.warning(
                "last message should be of performative accept or match accept."
            )