コード例 #1
0
    def get_raw_transaction(
        self, api: LedgerApi, message: LedgerApiMessage, dialogue: LedgerApiDialogue,
    ) -> LedgerApiMessage:
        """
        Send the request 'get_raw_transaction'.

        :param api: the API object.
        :param message: the Ledger API message
        :return: None
        """
        raw_transaction = api.get_transfer_transaction(
            sender_address=message.terms.sender_address,
            destination_address=message.terms.counterparty_address,
            amount=message.terms.sender_payable_amount,
            tx_fee=message.terms.fee,
            tx_nonce=message.terms.nonce,
            **message.terms.kwargs,
        )
        if raw_transaction is None:
            response = self.get_error_message(
                ValueError("No raw transaction returned"), api, message, dialogue
            )
        else:
            response = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.RAW_TRANSACTION,
                message_id=message.message_id + 1,
                target=message.message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                raw_transaction=RawTransaction(
                    message.terms.ledger_id, raw_transaction
                ),
            )
            response.counterparty = message.counterparty
            dialogue.update(response)
        return response
コード例 #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 = 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
コード例 #3
0
ファイル: handlers.py プロジェクト: vishalbelsare/agents-aea
    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
        """
        self.context.logger.info(
            "[{}]: transaction signing was successful.".format(
                self.context.agent_name))
        ledger_api_dialogues = cast(LedgerApiDialogues,
                                    self.context.ledger_api_dialogues)
        ledger_api_msg = LedgerApiMessage(
            performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION,
            dialogue_reference=ledger_api_dialogues.
            new_self_initiated_dialogue_reference(),
            signed_transaction=signing_msg.signed_transaction,
        )
        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, "Error when creating signing dialogue."
        ledger_api_dialogue.associated_signing_dialogue = signing_dialogue
        self.context.outbox.put_message(message=ledger_api_msg)
        self.context.logger.info("[{}]: sending transaction to ledger.".format(
            self.context.agent_name))
コード例 #4
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
        """
        self.context.logger.info("transaction signing was successful.")
        fipa_dialogue = signing_dialogue.associated_fipa_dialogue
        ledger_api_dialogue = fipa_dialogue.associated_ledger_api_dialogue
        last_ledger_api_msg = ledger_api_dialogue.last_incoming_message
        assert (last_ledger_api_msg is not None
                ), "Could not retrieve last message in ledger api dialogue"
        ledger_api_msg = LedgerApiMessage(
            performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION,
            dialogue_reference=ledger_api_dialogue.dialogue_label.
            dialogue_reference,
            target=last_ledger_api_msg.message_id,
            message_id=last_ledger_api_msg.message_id + 1,
            signed_transaction=signing_msg.signed_transaction,
        )
        ledger_api_msg.counterparty = LEDGER_API_ADDRESS
        ledger_api_dialogue.update(ledger_api_msg)
        self.context.outbox.put_message(message=ledger_api_msg)
        self.context.logger.info("sending transaction to ledger.")
コード例 #5
0
async def test_no_raw_tx():
    """Test no raw tx returned."""
    dispatcher = LedgerApiRequestDispatcher(ConnectionStatus())
    mock_api = Mock()
    contract_api_dialogues = ContractApiDialogues()
    message = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION,
        dialogue_reference=contract_api_dialogues.
        new_self_initiated_dialogue_reference(),
        terms=Terms(
            ledger_id=EthereumCrypto.identifier,
            sender_address="1111",
            counterparty_address="22222",
            amount_by_currency_id={"ETH": -1},
            quantities_by_good_id={"some_service_id": 1},
            is_sender_payable_tx_fee=True,
            nonce="",
            fee_by_currency_id={"ETH": 10},
            chain_id=3,
        ),
    )
    message.counterparty = "test"
    dialogue = contract_api_dialogues.update(message)
    mock_api.get_transfer_transaction.return_value = None
    msg = dispatcher.get_raw_transaction(mock_api, message, dialogue)

    assert msg.performative == LedgerApiMessage.Performative.ERROR
コード例 #6
0
ファイル: handlers.py プロジェクト: vishalbelsare/agents-aea
    def _handle_transaction_digest(
            self, ledger_api_msg: LedgerApiMessage,
            ledger_api_dialogue: LedgerApiDialogue) -> None:
        """
        Handle a message of transaction_digest performative.

        :param ledger_api_message: the ledger api message
        :param ledger_api_dialogue: the ledger api dialogue
        """
        self.context.logger.info(
            "[{}]: transaction was successfully submitted. Transaction digest={}"
            .format(self.context.agent_name,
                    ledger_api_msg.transaction_digest))
        msg = LedgerApiMessage(
            performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
            message_id=ledger_api_msg.message_id + 1,
            dialogue_reference=ledger_api_dialogue.dialogue_label.
            dialogue_reference,
            target=ledger_api_msg.message_id,
            transaction_digest=ledger_api_msg.transaction_digest,
        )
        msg.counterparty = ledger_api_msg.counterparty
        ledger_api_dialogue.update(msg)
        self.context.outbox.put_message(message=msg)
        self.context.logger.info(
            "[{}]: requesting transaction receipt.".format(
                self.context.agent_name))
コード例 #7
0
    def get_error_message(
        self, e: Exception, api: LedgerApi, message: Message, dialogue: BaseDialogue,
    ) -> LedgerApiMessage:
        """
        Build an error message.

        :param e: the exception.
        :param api: the Ledger API.
        :param message: the request message.
        :return: an error message response.
        """
        message = cast(LedgerApiMessage, message)
        dialogue = cast(LedgerApiDialogue, dialogue)
        response = LedgerApiMessage(
            performative=LedgerApiMessage.Performative.ERROR,
            message_id=message.message_id + 1,
            target=message.message_id,
            dialogue_reference=dialogue.dialogue_label.dialogue_reference,
            code=500,
            message=str(e),
            data=b"",
        )
        response.counterparty = message.counterparty
        dialogue.update(response)
        return response
コード例 #8
0
    def get_balance(
        self, api: LedgerApi, message: LedgerApiMessage, dialogue: LedgerApiDialogue,
    ) -> LedgerApiMessage:
        """
        Send the request 'get_balance'.

        :param api: the API object.
        :param message: the Ledger API message
        :return: None
        """
        balance = api.get_balance(message.address)
        if balance is None:
            response = self.get_error_message(
                ValueError("No balance returned"), api, message, dialogue
            )
        else:
            response = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.BALANCE,
                message_id=message.message_id + 1,
                target=message.message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                balance=balance,
                ledger_id=message.ledger_id,
            )
            response.counterparty = message.counterparty
            dialogue.update(response)
        return response
コード例 #9
0
    def get_transaction_receipt(
        self,
        api: LedgerApi,
        message: LedgerApiMessage,
        dialogue: LedgerApiDialogue,
    ) -> LedgerApiMessage:
        """
        Send the request 'get_transaction_receipt'.

        :param api: the API object.
        :param message: the Ledger API message
        :return: None
        """
        is_settled = False
        attempts = 0
        while (not is_settled and attempts < self.MAX_ATTEMPTS
               and self.connection_state.get() == ConnectionStates.connected):
            time.sleep(self.TIMEOUT)
            transaction_receipt = api.get_transaction_receipt(
                message.transaction_digest.body)
            is_settled = api.is_transaction_settled(transaction_receipt)
            attempts += 1
        attempts = 0
        transaction = api.get_transaction(message.transaction_digest.body)
        while (transaction is None and attempts < self.MAX_ATTEMPTS
               and self.connection_state.get() == ConnectionStates.connected):
            time.sleep(self.TIMEOUT)
            transaction = api.get_transaction(message.transaction_digest.body)
            attempts += 1
        if not is_settled:  # pragma: nocover
            response = self.get_error_message(
                ValueError("Transaction not settled within timeout"),
                api,
                message,
                dialogue,
            )
        elif transaction_receipt is None:  # pragma: nocover
            response = self.get_error_message(
                ValueError("No transaction_receipt returned"), api, message,
                dialogue)
        elif transaction is None:  # pragma: nocover
            response = self.get_error_message(ValueError("No tx returned"),
                                              api, message, dialogue)
        else:
            response = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT,
                message_id=message.message_id + 1,
                target=message.message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                transaction_receipt=TransactionReceipt(
                    message.transaction_digest.ledger_id,
                    transaction_receipt,
                    transaction,
                ),
            )
            response.counterparty = message.counterparty
            dialogue.update(response)
        return response
コード例 #10
0
    def _handle_match_accept(
        self, fipa_msg: FipaMessage, fipa_dialogue: FipaDialogue
    ) -> None:
        """
        Handle the match accept.

        :param fipa_msg: the message
        :param fipa_dialogue: the dialogue object
        :return: None
        """
        self.context.logger.info(
            "received MATCH_ACCEPT_W_INFORM from sender={} with info={}".format(
                fipa_msg.counterparty[-5:], fipa_msg.info
            )
        )
        strategy = cast(GenericStrategy, self.context.strategy)
        if strategy.is_ledger_tx:
            transfer_address = fipa_msg.info.get("address", None)
            if transfer_address is not None and isinstance(transfer_address, str):
                fipa_dialogue.terms.counterparty_address = transfer_address
            ledger_api_dialogues = cast(
                LedgerApiDialogues, self.context.ledger_api_dialogues
            )
            ledger_api_msg = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION,
                dialogue_reference=ledger_api_dialogues.new_self_initiated_dialogue_reference(),
                terms=fipa_dialogue.terms,
            )
            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
            ), "Error when creating ledger api dialogue."
            ledger_api_dialogue.associated_fipa_dialogue = fipa_dialogue
            fipa_dialogue.associated_ledger_api_dialogue = ledger_api_dialogue
            self.context.outbox.put_message(message=ledger_api_msg)
            self.context.logger.info(
                "requesting transfer transaction from ledger api..."
            )
        else:
            inform_msg = FipaMessage(
                message_id=fipa_msg.message_id + 1,
                dialogue_reference=fipa_dialogue.dialogue_label.dialogue_reference,
                target=fipa_msg.message_id,
                performative=FipaMessage.Performative.INFORM,
                info={"Done": "Sending payment via bank transfer"},
            )
            inform_msg.counterparty = fipa_msg.counterparty
            fipa_dialogue.update(inform_msg)
            self.context.outbox.put_message(message=inform_msg)
            self.context.logger.info(
                "informing counterparty={} of payment.".format(
                    fipa_msg.counterparty[-5:]
                )
            )
コード例 #11
0
ファイル: behaviours.py プロジェクト: ejfitzgerald/agents-aea
 def setup(self) -> None:
     """Implement the setup for the behaviour."""
     strategy = cast(Strategy, self.context.strategy)
     ledger_api_dialogues = cast(
         LedgerApiDialogues, self.context.ledger_api_dialogues
     )
     ledger_api_msg = LedgerApiMessage(
         performative=LedgerApiMessage.Performative.GET_BALANCE,
         dialogue_reference=ledger_api_dialogues.new_self_initiated_dialogue_reference(),
         ledger_id=strategy.ledger_id,
         address=cast(str, self.context.agent_addresses.get(strategy.ledger_id)),
     )
     ledger_api_msg.counterparty = LEDGER_API_ADDRESS
     ledger_api_dialogues.update(ledger_api_msg)
     self.context.outbox.put_message(message=ledger_api_msg)
コード例 #12
0
async def test_no_balance():
    """Test no balance."""
    dispatcher = LedgerApiRequestDispatcher(AsyncState())
    mock_api = Mock()
    message = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_BALANCE,
        dialogue_reference=dispatcher.dialogues.
        new_self_initiated_dialogue_reference(),
        ledger_id=ETHEREUM,
        address="test",
    )
    message.counterparty = "test"
    dialogue = dispatcher.dialogues.update(message)
    mock_api.get_balance.return_value = None
    msg = dispatcher.get_balance(mock_api, message, dialogue)

    assert msg.performative == LedgerApiMessage.Performative.ERROR
コード例 #13
0
async def test_no_balance():
    """Test no balance."""
    dispatcher = LedgerApiRequestDispatcher(ConnectionStatus())
    mock_api = Mock()
    contract_api_dialogues = ContractApiDialogues()
    message = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_BALANCE,
        dialogue_reference=contract_api_dialogues.
        new_self_initiated_dialogue_reference(),
        ledger_id=EthereumCrypto.identifier,
        address="test",
    )
    message.counterparty = "test"
    dialogue = contract_api_dialogues.update(message)
    mock_api.get_balance.return_value = None
    msg = dispatcher.get_balance(mock_api, message, dialogue)

    assert msg.performative == LedgerApiMessage.Performative.ERROR
コード例 #14
0
ファイル: behaviours.py プロジェクト: ejfitzgerald/agents-aea
    def _request_balance(self) -> None:
        """
        Request ledger balance.

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        ledger_api_dialogues = cast(
            LedgerApiDialogues, self.context.ledger_api_dialogues
        )
        ledger_api_msg = LedgerApiMessage(
            performative=LedgerApiMessage.Performative.GET_BALANCE,
            dialogue_reference=ledger_api_dialogues.new_self_initiated_dialogue_reference(),
            ledger_id=strategy.ledger_id,
            address=cast(str, self.context.agent_addresses.get(strategy.ledger_id)),
        )
        ledger_api_msg.counterparty = LEDGER_API_ADDRESS
        ledger_api_dialogues.update(ledger_api_msg)
        self.context.outbox.put_message(message=ledger_api_msg)
コード例 #15
0
async def test_get_balance(ledger_id, address, config,
                           ledger_apis_connection: Connection):
    """Test get balance."""
    import aea  # noqa # to load registries

    ledger_api_dialogues = LedgerApiDialogues(address)
    request = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_BALANCE,
        dialogue_reference=ledger_api_dialogues.
        new_self_initiated_dialogue_reference(),
        ledger_id=ledger_id,
        address=address,
    )

    request.counterparty = str(ledger_apis_connection.connection_id)
    ledger_api_dialogue = ledger_api_dialogues.update(request)
    assert ledger_api_dialogue is not None
    envelope = Envelope(
        to=str(ledger_apis_connection.connection_id),
        sender=address,
        protocol_id=request.protocol_id,
        message=request,
    )

    await ledger_apis_connection.send(envelope)
    await asyncio.sleep(0.01)
    response = await ledger_apis_connection.receive()

    assert response is not None
    assert type(response.message) == LedgerApiMessage
    response_msg_orig = cast(LedgerApiMessage, response.message)
    response_msg = copy.copy(response_msg_orig)
    response_msg.is_incoming = True
    response_msg.counterparty = response_msg_orig.sender
    response_dialogue = ledger_api_dialogues.update(response_msg)
    assert response_dialogue == ledger_api_dialogue
    assert response_msg.performative == LedgerApiMessage.Performative.BALANCE
    actual_balance_amount = response_msg.balance
    expected_balance_amount = make_ledger_api(ledger_id,
                                              **config).get_balance(address)
    assert actual_balance_amount == expected_balance_amount
コード例 #16
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
コード例 #17
0
    def setup(self) -> None:
        """
        Implement the setup.

        :return: None
        """
        strategy = cast(GenericStrategy, self.context.strategy)
        if strategy.is_ledger_tx:
            ledger_api_dialogues = cast(LedgerApiDialogues,
                                        self.context.ledger_api_dialogues)
            ledger_api_msg = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.GET_BALANCE,
                dialogue_reference=ledger_api_dialogues.
                new_self_initiated_dialogue_reference(),
                ledger_id=strategy.ledger_id,
                address=cast(
                    str, self.context.agent_addresses.get(strategy.ledger_id)),
            )
            ledger_api_msg.counterparty = LEDGER_API_ADDRESS
            ledger_api_dialogues.update(ledger_api_msg)
            self.context.outbox.put_message(message=ledger_api_msg)
        self._register_agent()
        self._register_service()
コード例 #18
0
    def _handle_terms(self, ml_trade_msg: MlTradeMessage,
                      ml_trade_dialogue: MlTradeDialogue) -> None:
        """
        Handle the terms of the request.

        :param ml_trade_msg: the ml trade message
        :param ml_trade_dialogue: the dialogue object
        :return: None
        """
        terms = ml_trade_msg.terms
        self.context.logger.info(
            "received terms message from {}: terms={}".format(
                ml_trade_msg.counterparty[-5:], terms.values))

        strategy = cast(Strategy, self.context.strategy)
        acceptable = strategy.is_acceptable_terms(terms)
        affordable = strategy.is_affordable_terms(terms)
        if not acceptable and affordable:
            self.context.logger.info(
                "rejecting, terms are not acceptable and/or affordable")
            return

        if strategy.is_ledger_tx:
            # construct a tx for settlement on the ledger
            ledger_api_dialogues = cast(LedgerApiDialogues,
                                        self.context.ledger_api_dialogues)
            ledger_api_msg = LedgerApiMessage(
                performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION,
                dialogue_reference=ledger_api_dialogues.
                new_self_initiated_dialogue_reference(),
                terms=Terms(
                    ledger_id=terms.values["ledger_id"],
                    sender_address=self.context.agent_addresses[
                        terms.values["ledger_id"]],
                    counterparty_address=terms.values["address"],
                    amount_by_currency_id={
                        terms.values["currency_id"]: -terms.values["price"]
                    },
                    is_sender_payable_tx_fee=True,
                    quantities_by_good_id={"ml_training_data": 1},
                    nonce=uuid.uuid4().hex,
                    fee_by_currency_id={terms.values["currency_id"]: 1},
                ),
            )
            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), "Error when creating ledger api dialogue."
            ledger_api_dialogue.associated_ml_trade_dialogue = ml_trade_dialogue
            self.context.outbox.put_message(message=ledger_api_msg)
            self.context.logger.info(
                "requesting transfer transaction from ledger api...")
        else:
            # accept directly with a dummy transaction digest, no settlement
            ml_accept = MlTradeMessage(
                performative=MlTradeMessage.Performative.ACCEPT,
                dialogue_reference=ml_trade_dialogue.dialogue_label.
                dialogue_reference,
                message_id=ml_trade_msg.message_id + 1,
                target=ml_trade_msg.message_id,
                tx_digest=DUMMY_DIGEST,
                terms=terms,
            )
            ml_accept.counterparty = ml_trade_msg.counterparty
            ml_trade_dialogue.update(ml_accept)
            self.context.outbox.put_message(message=ml_accept)
            self.context.logger.info("sending dummy transaction digest ...")
コード例 #19
0
async def test_send_signed_transaction_ethereum(
        ledger_apis_connection: Connection):
    """Test send signed transaction with Ethereum APIs."""
    import aea  # noqa # to load registries

    crypto1 = EthereumCrypto(private_key_path=ETHEREUM_PRIVATE_KEY_PATH)
    crypto2 = EthereumCrypto()
    api = aea.crypto.registries.make_ledger_api(EthereumCrypto.identifier,
                                                **ETHEREUM_TESTNET_CONFIG)
    api = cast(EthereumApi, api)
    ledger_api_dialogues = LedgerApiDialogues()

    amount = 40000
    fee = 30000

    request = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION,
        dialogue_reference=ledger_api_dialogues.
        new_self_initiated_dialogue_reference(),
        terms=Terms(
            ledger_id=EthereumCrypto.identifier,
            sender_address=crypto1.address,
            counterparty_address=crypto2.address,
            amount_by_currency_id={"ETH": -amount},
            quantities_by_good_id={"some_service_id": 1},
            is_sender_payable_tx_fee=True,
            nonce="",
            fee_by_currency_id={"ETH": fee},
            chain_id=3,
        ),
    )
    request.counterparty = str(ledger_apis_connection.connection_id)
    ledger_api_dialogue = ledger_api_dialogues.update(request)
    assert ledger_api_dialogue is not None
    envelope = Envelope(
        to=str(ledger_apis_connection.connection_id),
        sender=crypto1.address,
        protocol_id=request.protocol_id,
        message=request,
    )
    await ledger_apis_connection.send(envelope)
    await asyncio.sleep(0.01)
    response = await ledger_apis_connection.receive()

    assert response is not None
    assert type(response.message) == LedgerApiMessage
    response_message = cast(LedgerApiMessage, response.message)
    assert (response_message.performative ==
            LedgerApiMessage.Performative.RAW_TRANSACTION)
    response_dialogue = ledger_api_dialogues.update(response_message)
    assert response_dialogue == ledger_api_dialogue
    assert type(response_message.raw_transaction) == RawTransaction
    assert response_message.raw_transaction.ledger_id == request.terms.ledger_id

    # raw_tx = api.get_transfer_transaction(
    #     sender_address=crypto1.address,
    #     destination_address=crypto2.address,
    #     amount=amount,
    #     tx_fee=fee,
    #     tx_nonce="",
    #     chain_id=3,
    # )

    signed_transaction = crypto1.sign_transaction(
        response_message.raw_transaction.body)
    request = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION,
        dialogue_reference=ledger_api_dialogue.dialogue_label.
        dialogue_reference,
        signed_transaction=SignedTransaction(EthereumCrypto.identifier,
                                             signed_transaction),
    )
    request.counterparty = str(ledger_apis_connection.connection_id)
    ledger_api_dialogue.update(request)
    envelope = Envelope(
        to=str(ledger_apis_connection.connection_id),
        sender=crypto1.address,
        protocol_id=request.protocol_id,
        message=request,
    )
    await ledger_apis_connection.send(envelope)
    await asyncio.sleep(0.01)
    response = await ledger_apis_connection.receive()

    assert response is not None
    assert type(response.message) == LedgerApiMessage
    response_message = cast(LedgerApiMessage, response.message)
    assert (response_message.performative !=
            LedgerApiMessage.Performative.ERROR
            ), f"Received error: {response_message.message}"
    assert (response_message.performative ==
            LedgerApiMessage.Performative.TRANSACTION_DIGEST)
    response_dialogue = ledger_api_dialogues.update(response_message)
    assert response_dialogue == ledger_api_dialogue
    assert type(response_message.transaction_digest) == TransactionDigest
    assert type(response_message.transaction_digest.body) == str
    assert (response_message.transaction_digest.ledger_id ==
            request.signed_transaction.ledger_id)
    assert type(response_message.transaction_digest.body.startswith("0x"))

    request = LedgerApiMessage(
        performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT,
        dialogue_reference=ledger_api_dialogue.dialogue_label.
        dialogue_reference,
        transaction_digest=response_message.transaction_digest,
    )
    request.counterparty = str(ledger_apis_connection.connection_id)
    ledger_api_dialogue.update(request)
    envelope = Envelope(
        to=str(ledger_apis_connection.connection_id),
        sender=crypto1.address,
        protocol_id=request.protocol_id,
        message=request,
    )
    await ledger_apis_connection.send(envelope)
    await asyncio.sleep(0.01)
    response = await ledger_apis_connection.receive()

    assert response is not None
    assert type(response.message) == LedgerApiMessage
    response_message = cast(LedgerApiMessage, response.message)
    assert (response_message.performative ==
            LedgerApiMessage.Performative.TRANSACTION_RECEIPT)
    response_dialogue = ledger_api_dialogues.update(response_message)
    assert response_dialogue == ledger_api_dialogue
    assert type(response_message.transaction_receipt) == TransactionReceipt
    assert response_message.transaction_receipt.receipt is not None
    assert response_message.transaction_receipt.transaction is not None
    assert (response_message.transaction_receipt.ledger_id ==
            request.transaction_digest.ledger_id)
コード例 #20
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:]))