Esempio n. 1
0
def test_transaction_digest_encode_decode():
    """Test encoding and decoding of transaction_digest."""
    class TransactionDigestProtobufObject:
        transaction_digest_bytes = b""

    ledger_id = "some_ledger"
    body = "digest"
    td = TransactionDigest(ledger_id, body)
    TransactionDigest.encode(TransactionDigestProtobufObject, td)
    recovered_td = TransactionDigest.decode(TransactionDigestProtobufObject)
    assert td == recovered_td
Esempio n. 2
0
    def send_signed_transaction(
        self, api: LedgerApi, message: LedgerApiMessage, dialogue: LedgerApiDialogue,
    ) -> LedgerApiMessage:
        """
        Send the request 'send_signed_tx'.

        :param api: the API object.
        :param message: the Ledger API message
        :return: None
        """
        transaction_digest = api.send_signed_transaction(
            message.signed_transaction.body
        )
        if transaction_digest is None:  # pragma: nocover
            response = self.get_error_message(
                ValueError("No transaction_digest returned"), api, message, dialogue
            )
        else:
            response = cast(
                LedgerApiMessage,
                dialogue.reply(
                    performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST,
                    target_message=message,
                    transaction_digest=TransactionDigest(
                        message.signed_transaction.ledger_id, transaction_digest
                    ),
                ),
            )
        return response
    def send_signed_transaction(
        self, api: LedgerApi, message: LedgerApiMessage, dialogue: LedgerApiDialogue,
    ) -> LedgerApiMessage:
        """
        Send the request 'send_signed_tx'.

        :param api: the API object.
        :param message: the Ledger API message
        :return: None
        """
        transaction_digest = api.send_signed_transaction(
            message.signed_transaction.body
        )
        if transaction_digest is None:  # pragma: nocover
            response = self.get_error_message(
                ValueError("No transaction_digest returned"), api, message, dialogue
            )
        else:
            response = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST,
                message_id=message.message_id + 1,
                target=message.message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                transaction_digest=TransactionDigest(
                    message.signed_transaction.ledger_id, transaction_digest
                ),
            )
            response.counterparty = message.counterparty
            dialogue.update(response)
        return response
Esempio n. 4
0
    def _handle_inform(self, fipa_msg: FipaMessage,
                       fipa_dialogue: FipaDialogue) -> 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 data, otherwise do nothing.

        :param fipa_msg: the message
        :param fipa_dialogue: the dialogue object
        :return: None
        """
        self.context.logger.info("received INFORM from sender={}".format(
            fipa_msg.sender[-5:]))

        strategy = cast(GenericStrategy, self.context.strategy)
        if strategy.is_ledger_tx and "transaction_digest" in fipa_msg.info.keys(
        ):
            self.context.logger.info(
                "checking whether transaction={} has been received ...".format(
                    fipa_msg.info["transaction_digest"]))
            ledger_api_dialogues = cast(LedgerApiDialogues,
                                        self.context.ledger_api_dialogues)
            ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create(
                counterparty=LEDGER_API_ADDRESS,
                performative=LedgerApiMessage.Performative.
                GET_TRANSACTION_RECEIPT,
                transaction_digest=TransactionDigest(
                    fipa_dialogue.terms.ledger_id,
                    fipa_msg.info["transaction_digest"]),
            )
            ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue)
            ledger_api_dialogue.associated_fipa_dialogue = fipa_dialogue
            self.context.outbox.put_message(message=ledger_api_msg)
        elif strategy.is_ledger_tx:
            self.context.logger.warning(
                "did not receive transaction digest from sender={}.".format(
                    fipa_msg.sender[-5:]))
        elif not strategy.is_ledger_tx and "Done" in fipa_msg.info.keys():
            inform_msg = fipa_dialogue.reply(
                performative=FipaMessage.Performative.INFORM,
                target_message=fipa_msg,
                info=fipa_dialogue.data_for_sale,
            )
            self.context.outbox.put_message(message=inform_msg)
            fipa_dialogues = cast(FipaDialogues, self.context.fipa_dialogues)
            fipa_dialogues.dialogue_stats.add_dialogue_endstate(
                FipaDialogue.EndState.SUCCESSFUL,
                fipa_dialogue.is_self_initiated)
            self.context.logger.info(
                "transaction confirmed, sending data={} to buyer={}.".format(
                    fipa_dialogue.data_for_sale,
                    fipa_msg.sender[-5:],
                ))
        else:
            self.context.logger.warning(
                "did not receive transaction confirmation from sender={}.".
                format(fipa_msg.sender[-5:]))
Esempio n. 5
0
def test_init_transaction_digest():
    """Test the transaction_digest object initialization."""
    ledger_id = "some_ledger"
    body = "digest"
    td = TransactionDigest(ledger_id, body)
    assert td.ledger_id == ledger_id
    assert td.body == body
    assert str(td) == "TransactionDigest: ledger_id={}, body={}".format(ledger_id, body)
    assert td == td
Esempio n. 6
0
 def setup(cls):
     """Setup the test class."""
     super().setup()
     cls.ledger_api_handler = cast(
         GenericLedgerApiHandler,
         cls._skill.skill_context.handlers.ledger_api)
     cls.strategy = cast(GenericStrategy, cls._skill.skill_context.strategy)
     cls.fipa_dialogues = cast(FipaDialogues,
                               cls._skill.skill_context.fipa_dialogues)
     cls.ledger_api_dialogues = cast(
         LedgerApiDialogues, cls._skill.skill_context.ledger_api_dialogues)
     cls.terms = Terms(
         "some_ledger_id",
         cls._skill.skill_context.agent_address,
         "counterprty",
         {"currency_id": 50},
         {"good_id": -10},
         "some_nonce",
     )
     cls.list_of_fipa_messages = (
         DialogueMessage(FipaMessage.Performative.CFP,
                         {"query": "some_query"}, True),
         DialogueMessage(FipaMessage.Performative.PROPOSE,
                         {"proposal": "some_proposal"}),
         DialogueMessage(FipaMessage.Performative.ACCEPT),
         DialogueMessage(
             FipaMessage.Performative.MATCH_ACCEPT_W_INFORM,
             {"info": {
                 "address": "some_term_sender_address"
             }},
         ),
         DialogueMessage(
             FipaMessage.Performative.INFORM,
             {
                 "info": {
                     "transaction_digest": "some_transaction_digest_body"
                 }
             },
         ),
     )
     cls.transaction_digest = TransactionDigest("some_ledger_id",
                                                "some_body")
     cls.transaction_receipt = TransactionReceipt("some_ledger_id",
                                                  "some_receipt",
                                                  "some_transaction")
     cls.list_of_ledger_api_messages = (
         DialogueMessage(
             LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
             {"transaction_digest": cls.transaction_digest},
         ),
         DialogueMessage(
             LedgerApiMessage.Performative.TRANSACTION_RECEIPT,
             {"transaction_receipt": cls.transaction_receipt},
         ),
     )
Esempio n. 7
0
    def test_handle_inform_is_ledger_tx_and_with_tx_digest(self):
        """Test the _handle_inform method of the fipa handler where is_ledger_tx is True and info contains transaction_digest."""
        # setup
        self.strategy._is_ledger_tx = True
        tx_digest = "some_transaction_digest_body"
        ledger_id = "some_ledger_id"

        fipa_dialogue = self.prepare_skill_dialogue(
            dialogues=self.fipa_dialogues,
            messages=self.list_of_messages[:4],
        )
        fipa_dialogue.terms = Terms(
            ledger_id,
            self.skill.skill_context.agent_address,
            "counterprty",
            {"currency_id": 50},
            {"good_id": -10},
            "some_nonce",
        )
        incoming_message = self.build_incoming_message_for_skill_dialogue(
            dialogue=fipa_dialogue,
            performative=FipaMessage.Performative.INFORM,
            info={"transaction_digest": tx_digest},
        )

        # operation
        with patch.object(self.fipa_handler.context.logger,
                          "log") as mock_logger:
            self.fipa_handler.handle(incoming_message)
        incoming_message = cast(FipaMessage, incoming_message)

        # after
        mock_logger.assert_any_call(
            logging.INFO,
            f"received INFORM from sender={COUNTERPARTY_ADDRESS[-5:]}")
        mock_logger.assert_any_call(
            logging.INFO,
            f"checking whether transaction={incoming_message.info['transaction_digest']} has been received ...",
        )

        self.assert_quantity_in_outbox(1)
        has_attributes, error_str = self.message_has_attributes(
            actual_message=self.get_message_from_outbox(),
            message_type=LedgerApiMessage,
            performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
            to=LEDGER_API_ADDRESS,
            sender=self.skill.skill_context.agent_address,
            target=0,
            transaction_digest=TransactionDigest(ledger_id, tx_digest),
        )
        assert has_attributes, error_str
Esempio n. 8
0
async def test_attempts_get_transaction_receipt():
    """Test retry and sleep."""
    dispatcher = LedgerApiRequestDispatcher(ConnectionStatus())
    dispatcher.connection_status.is_connected = True
    mock_api = Mock()
    contract_api_dialogues = ContractApiDialogues()
    message = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
        dialogue_reference=contract_api_dialogues.
        new_self_initiated_dialogue_reference(),
        transaction_digest=TransactionDigest("asdad", "sdfdsf"),
    )
    message.counterparty = "test"
    dialogue = contract_api_dialogues.update(message)
    mock_api.get_transaction.return_value = None
    mock_api.is_transaction_settled.return_value = True
    with patch.object(dispatcher, "MAX_ATTEMPTS", 2):
        with patch.object(dispatcher, "TIMEOUT", 0.001):
            msg = dispatcher.get_transaction_receipt(mock_api, message,
                                                     dialogue)

    assert msg.performative == LedgerApiMessage.Performative.ERROR
Esempio n. 9
0
    def setup(cls):
        """Setup the test class."""
        super().setup()
        cls.ledger_api_handler = cast(
            LedgerApiHandler, cls._skill.skill_context.handlers.ledger_api)
        cls.ledger_api_dialogues = cast(
            LedgerApiDialogues, cls._skill.skill_context.ledger_api_dialogues)
        cls.signing_dialogues = cast(
            SigningDialogues, cls._skill.skill_context.signing_dialogues)
        cls.contract_api_dialogues = cast(
            ContractApiDialogues,
            cls._skill.skill_context.contract_api_dialogues)
        cls.parameters = cast(Parameters, cls._skill.skill_context.parameters)
        cls.game = cast(Game, cls._skill.skill_context.game)

        cls.logger = cls.ledger_api_handler.context.logger

        cls.ledger_id = "some_ledger_id"
        cls.contract_id = "some_contract_id"
        cls.callable = "some_callable"
        cls.kwargs = Kwargs({"some_key": "some_value"})

        cls.body = {"some_key": "some_value"}
        cls.body_str = "some_body"
        cls.contract_address = "some_contract_address"

        cls.raw_transaction = RawTransaction(cls.ledger_id, cls.body)
        cls.signed_transaction = SignedTransaction(cls.ledger_id, cls.body)
        cls.transaction_digest = TransactionDigest(cls.ledger_id, cls.body_str)
        cls.receipt = {"contractAddress": cls.contract_address}
        cls.transaction_receipt = TransactionReceipt(
            cls.ledger_id, cls.receipt,
            {"transaction_key": "transaction_value"})

        cls.terms = Terms(
            cls.ledger_id,
            cls._skill.skill_context.agent_address,
            "counterprty",
            {"currency_id": 50},
            {"good_id": -10},
            "some_nonce",
        )

        cls.list_of_signing_messages = (DialogueMessage(
            SigningMessage.Performative.SIGN_TRANSACTION,
            {
                "terms":
                cls.terms,
                "raw_transaction":
                SigningMessage.RawTransaction(cls.ledger_id, cls.body),
            },
        ), )
        cls.list_of_contract_api_messages = (DialogueMessage(
            ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION,
            {
                "ledger_id": cls.ledger_id,
                "contract_id": cls.contract_id,
                "callable": cls.callable,
                "kwargs": cls.kwargs,
            },
        ), )
        cls.list_of_ledger_api_messages = (
            DialogueMessage(LedgerApiMessage.Performative.GET_RAW_TRANSACTION,
                            {"terms": cls.terms}),
            DialogueMessage(
                LedgerApiMessage.Performative.RAW_TRANSACTION,
                {"raw_transaction": cls.raw_transaction},
            ),
            DialogueMessage(
                LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION,
                {"signed_transaction": cls.signed_transaction},
            ),
            DialogueMessage(
                LedgerApiMessage.Performative.TRANSACTION_DIGEST,
                {"transaction_digest": cls.transaction_digest},
            ),
            DialogueMessage(
                LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
                {"transaction_digest": cls.transaction_digest},
            ),
        )
Esempio n. 10
0
    def _handle_inform(self, fipa_msg: FipaMessage,
                       fipa_dialogue: FipaDialogue) -> 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 data, otherwise do nothing.

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

        strategy = cast(GenericStrategy, self.context.strategy)
        if strategy.is_ledger_tx and "transaction_digest" in fipa_msg.info.keys(
        ):
            self.context.logger.info(
                "[{}]: checking whether transaction={} has been received ...".
                format(self.context.agent_name,
                       fipa_msg.info["transaction_digest"]))
            ledger_api_dialogues = cast(LedgerApiDialogues,
                                        self.context.ledger_api_dialogues)
            ledger_api_msg = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.
                GET_TRANSACTION_RECEIPT,
                dialogue_reference=ledger_api_dialogues.
                new_self_initiated_dialogue_reference(),
                transaction_digest=TransactionDigest(
                    fipa_dialogue.terms.ledger_id,
                    fipa_msg.info["transaction_digest"]),
            )
            ledger_api_msg.counterparty = LEDGER_API_ADDRESS
            ledger_api_dialogue = cast(
                Optional[LedgerApiDialogue],
                ledger_api_dialogues.update(ledger_api_msg))
            assert (ledger_api_dialogue
                    is not None), "LedgerApiDialogue construction failed."
            ledger_api_dialogue.associated_fipa_dialogue = fipa_dialogue
            self.context.outbox.put_message(message=ledger_api_msg)
        elif strategy.is_ledger_tx:
            self.context.logger.warning(
                "[{}]: did not receive transaction digest from sender={}.".
                format(self.context.agent_name, fipa_msg.counterparty[-5:]))
        elif not strategy.is_ledger_tx and "Done" in fipa_msg.info.keys():
            inform_msg = FipaMessage(
                message_id=new_message_id,
                dialogue_reference=fipa_dialogue.dialogue_label.
                dialogue_reference,
                target=new_target,
                performative=FipaMessage.Performative.INFORM,
                info=fipa_dialogue.data_for_sale,
            )
            inform_msg.counterparty = fipa_msg.counterparty
            fipa_dialogue.update(inform_msg)
            self.context.outbox.put_message(message=inform_msg)
            fipa_dialogues = cast(FipaDialogues, self.context.fipa_dialogues)
            fipa_dialogues.dialogue_stats.add_dialogue_endstate(
                FipaDialogue.EndState.SUCCESSFUL,
                fipa_dialogue.is_self_initiated)
            self.context.logger.info(
                "[{}]: transaction confirmed, sending data={} to buyer={}.".
                format(
                    self.context.agent_name,
                    fipa_dialogue.data_for_sale,
                    fipa_msg.counterparty[-5:],
                ))
        else:
            self.context.logger.warning(
                "[{}]: did not receive transaction confirmation from sender={}."
                .format(self.context.agent_name, fipa_msg.counterparty[-5:]))