예제 #1
0
def test_raw_transaction_serialization():
    """Test the serialization for 'raw_transaction' speech-act works."""
    raw_transaction_arg = ContractApiMessage.RawTransaction(
        "some_ledger_id", {"body": "some_body"})
    msg = ContractApiMessage(
        message_id=2,
        target=1,
        performative=ContractApiMessage.Performative.RAW_TRANSACTION,
        raw_transaction=raw_transaction_arg,
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
예제 #2
0
def test_raw_message_serialization():
    """Test the serialization for 'raw_message' speech-act works."""
    raw_message_arg = ContractApiMessage.RawMessage("some_ledger_id",
                                                    b"some_body")
    msg = ContractApiMessage(
        performative=ContractApiMessage.Performative.RAW_MESSAGE,
        raw_message=raw_message_arg,
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
예제 #3
0
def test_error_serialization():
    """Test the serialization for 'error' speech-act works."""
    msg = ContractApiMessage(
        performative=ContractApiMessage.Performative.ERROR,
        code=7,
        message="some_error_message",
        data=b"some_error_data",
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
예제 #4
0
    def _request_token_create_transaction(self) -> None:
        """
        Request token create transaction

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg = ContractApiMessage(
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            dialogue_reference=contract_api_dialogues.
            new_self_initiated_dialogue_reference(),
            ledger_id=strategy.ledger_id,
            contract_id="fetchai/erc1155:0.6.0",
            contract_address=strategy.contract_address,
            callable="get_create_batch_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "deployer_address": self.context.agent_address,
                "token_ids": strategy.token_ids,
            }),
        )
        contract_api_msg.counterparty = LEDGER_API_ADDRESS
        contract_api_dialogue = cast(
            Optional[ContractApiDialogue],
            contract_api_dialogues.update(contract_api_msg),
        )
        assert contract_api_dialogue is not None, "ContractApiDialogue not generated"
        contract_api_dialogue.terms = strategy.get_create_token_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info(
            "[{}]: Requesting create batch transaction...".format(
                self.context.agent_name))
예제 #5
0
def test_state_serialization():
    """Test the serialization for 'state' speech-act works."""
    state_arg = ContractApiMessage.State("some_ledger_id",
                                         {"key": "some_body"})
    msg = ContractApiMessage(
        message_id=1,
        dialogue_reference=(str(0), ""),
        target=0,
        performative=ContractApiMessage.Performative.STATE,
        state=state_arg,
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
예제 #6
0
def test_get_raw_transaction_serialization():
    """Test the serialization for 'get_raw_transaction' speech-act works."""
    kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2})
    msg = ContractApiMessage(
        message_id=1,
        dialogue_reference=(str(0), ""),
        target=0,
        performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
        ledger_id="some_ledger_id",
        contract_id="some_contract_id",
        contract_address="some_contract_address",
        callable="some_callable",
        kwargs=kwargs_arg,
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (expected_envelope.protocol_specification_id ==
            actual_envelope.protocol_specification_id)
    assert expected_envelope.message != actual_envelope.message

    actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
예제 #7
0
def test_kwargs():
    """Test the kwargs custom type."""
    body = {"key_1": 1, "key_2": 2}
    kwargs = ContractApiMessage.Kwargs(body)
    assert str(kwargs) == "Kwargs: body={}".format(body)

    with pytest.raises(ValueError, match="body must not be None"):
        ContractApiMessage.Kwargs(None)
예제 #8
0
def test_incorrect_message(mocked_enforce):
    """Test that we raise an exception when the message is incorrect."""
    with mock.patch.object(contract_api_message_logger, "error") as mock_logger:
        ContractApiMessage(
            message_id=1,
            dialogue_reference=(str(0), ""),
            target=0,
            performative=ContractApiMessage.Performative.RAW_MESSAGE,
            raw_message=ContractApiMessage.RawMessage("some_ledger_id", b"some_body"),
        )

        mock_logger.assert_any_call("some error")
예제 #9
0
def test_encoding_unknown_performative():
    """Test that we raise an exception when the performative is unknown during encoding."""
    msg = ContractApiMessage(
        message_id=1,
        dialogue_reference=(str(0), ""),
        target=0,
        performative=ContractApiMessage.Performative.RAW_MESSAGE,
        raw_message=ContractApiMessage.RawMessage("some_ledger_id", b"some_body"),
    )

    with pytest.raises(ValueError, match="Performative not valid:"):
        with mock.patch.object(
            ContractApiMessage.Performative, "__eq__", return_value=False
        ):
            ContractApiMessage.serializer.encode(msg)
예제 #10
0
    def _request_token_mint_transaction(self) -> None:
        """
        Request token mint transaction

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=strategy.contract_id,
            contract_address=strategy.contract_address,
            callable="get_mint_batch_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "deployer_address":
                self.context.agent_address,
                "recipient_address":
                self.context.agent_address,
                "token_ids":
                strategy.token_ids,
                "mint_quantities":
                strategy.mint_quantities,
                "gas":
                strategy.gas,
            }),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_mint_token_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting mint batch transaction...")
예제 #11
0
    def _request_contract_state(self, contract_name: str, callable: str,
                                parameters: dict) -> None:
        """
        Request contract deploy transaction

        :return: None
        """
        params = {"deployer_address": self.context.agent_address}
        params.update(parameters)
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_STATE,
            ledger_id=strategy.ledger_id,
            contract_id=f"eightballer/{contract_name}:0.1.0",
            contract_address=strategy.deployment_status[contract_name][1],
            callable=callable,
            kwargs=ContractApiMessage.Kwargs(params),
        )
        contract_api_dialogue = cast(
            ContractApiDialogue,
            contract_api_dialogue,
        )
        contract_api_dialogue.terms = strategy.get_deploy_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        strategy.deployment_status[f"{contract_name}_{callable}"] = (
            "pending",
            contract_api_dialogue.dialogue_label.dialogue_reference[0],
        )
        strategy.deployment_status["status"] = "deploying"
        self.context.logger.info(
            f"requesting contract {contract_name} state transaction...")
예제 #12
0
 def _option_interaction(self, option_type: str, act: str,
                         params: Dict[str, Any]) -> None:
     if option_type not in ["btc", "eth"]:
         raise ValueError("Missing option types!")
     if act not in ["create_option", "exercise", "estimate"]:
         raise ValueError("Missing act types!")
     strategy = cast(Strategy, self.context.strategy)
     strategy.deployment_status["status"] = "deploying"
     strategy.is_behaviour_active = False
     contract_api_dialogues = cast(ContractApiDialogues,
                                   self.context.contract_api_dialogues)
     params.update({"deployer_address": self.context.agent_address})
     contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
         counterparty=LEDGER_API_ADDRESS,
         performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
         ledger_id=strategy.ledger_id,
         contract_id=f"eightballer/{option_type}options:0.1.0",
         contract_address=strategy.
         deployment_status[f"{option_type}options"][1],
         callable=f"{act}",
         kwargs=ContractApiMessage.Kwargs(params),
     )
     strategy.deployment_status[f"{option_type}options_{act}"] = (
         "pending",
         contract_api_dialogue.dialogue_label.dialogue_reference[0],
     )
     contract_api_dialogue = cast(
         ContractApiDialogue,
         contract_api_dialogue,
     )
     contract_api_dialogue.terms = strategy.get_deploy_terms()
     self.context.outbox.put_message(message=contract_api_msg)
     self.context.logger.info(
         f"contract deployer requesting {act} {option_type} transaction...")
예제 #13
0
    def _request_contract_deploy_transaction(self) -> None:
        """
        Request contract deployment transaction

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=str(LEDGER_API_ADDRESS),
            performative=ContractApiMessage.Performative.
            GET_DEPLOY_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=str(CLIENT_CONTRACT_PUBLIC_ID),
            callable="get_deploy_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "deployer_address":
                self.context.agent_address,
                "fetchOracleContractAddress":
                strategy.oracle_contract_address,
                "gas":
                strategy.default_gas_deploy,
            }),
        )
        contract_api_dialogue = cast(
            ContractApiDialogue,
            contract_api_dialogue,
        )
        contract_api_dialogue.terms = strategy.get_deploy_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info(
            "requesting contract deployment transaction...")
예제 #14
0
    def _request_query_transaction(self) -> None:
        """
        Request transaction that requests value from Fetch oracle contract

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=str(LEDGER_API_ADDRESS),
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=str(CLIENT_CONTRACT_PUBLIC_ID),
            contract_address=strategy.client_contract_address,
            callable="get_query_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "from_address": self.context.agent_address,
                "query_function": strategy.query_function,
                "gas": strategy.default_gas_query,
            }),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_query_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting query transaction...")
예제 #15
0
async def test_run_async():
    """Test run async error handled."""

    # for pydocstyle
    def _raise():
        raise Exception("Expected")

    contract_api_dialogues = ContractApiDialogues("address")
    request, dialogue = contract_api_dialogues.create(
        counterparty="str(ledger_apis_connection.connection_id)",
        performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
        ledger_id=ETHEREUM,
        contract_id=str(ERC1155_PUBLIC_ID),
        contract_address="test addr",
        callable="get_create_batch_transaction",
        kwargs=ContractApiMessage.Kwargs({
            "deployer_address":
            "test_addr",
            "token_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        }),
    )
    api = None
    msg = await ContractApiRequestDispatcher(MultiplexerStatus()).run_async(
        _raise, api, request, dialogue)
    assert msg.performative == ContractApiMessage.Performative.ERROR
예제 #16
0
    def test_handle_raw_transaction(self):
        """Test the _handle_raw_transaction method of the contract_api handler."""
        # setup
        contract_api_dialogue = cast(
            ContractApiDialogue,
            self.prepare_skill_dialogue(
                dialogues=self.contract_api_dialogues,
                messages=self.list_of_contract_api_messages[:1],
            ),
        )
        contract_api_dialogue.terms = self.terms
        incoming_message = self.build_incoming_message_for_skill_dialogue(
            dialogue=contract_api_dialogue,
            performative=ContractApiMessage.Performative.RAW_TRANSACTION,
            raw_transaction=ContractApiMessage.RawTransaction(LEDGER_ID, {}),
        )

        # operation
        with patch.object(self.logger, "log") as mock_logger:
            self.contract_api_handler.handle(incoming_message)

        # after
        mock_logger.assert_any_call(
            logging.INFO,
            f"received raw transaction={incoming_message}",
        )
        mock_logger.assert_any_call(
            logging.INFO,
            "proposing the transaction to the decision maker. Waiting for confirmation ...",
        )

        self.assert_quantity_in_decision_making_queue(1)
예제 #17
0
    def _request_grant_role_transaction(self) -> None:
        """
        Request transaction that grants oracle role in a Fetch oracle contract

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=str(LEDGER_API_ADDRESS),
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=str(CONTRACT_PUBLIC_ID),
            contract_address=strategy.contract_address,
            callable="get_grant_role_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "oracle_address":
                self.context.agent_address,
                "gas":
                strategy.default_gas_grant_role,
            }),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_grant_role_terms()
        envelope_context = EnvelopeContext(skill_id=self.context.skill_id,
                                           connection_id=LEDGER_API_ADDRESS)
        self.context.outbox.put_message(message=contract_api_msg,
                                        context=envelope_context)
        self.context.logger.info("requesting grant role transaction...")
예제 #18
0
    def _request_create_items_transaction(self, game: Game) -> None:
        """
        Request token create transaction

        :return: None
        """
        parameters = cast(Parameters, self.context.parameters)
        contract_api_dialogues = cast(
            ContractApiDialogues, self.context.contract_api_dialogues
        )
        token_ids = [int(good_id) for good_id in game.conf.good_id_to_name.keys()] + [
            int(currency_id) for currency_id in game.conf.currency_id_to_name.keys()
        ]
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=parameters.ledger_id,
            contract_id=parameters.contract_id,
            contract_address=parameters.contract_address,
            callable=ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION.value,
            kwargs=ContractApiMessage.Kwargs(
                {
                    "deployer_address": self.context.agent_address,
                    "token_ids": token_ids,
                    "gas": parameters.gas,
                }
            ),
        )
        contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
        contract_api_dialogue.terms = parameters.get_create_token_terms()
        contract_api_dialogue.callable = (
            ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION
        )
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting create items transaction...")
예제 #19
0
async def test_callable_cannot_find(erc1155_contract, ledger_apis_connection,
                                    caplog):
    """Test error messages when an exception is raised while processing the request."""
    address = ETHEREUM_ADDRESS_ONE
    contract_api_dialogues = ContractApiDialogues(address)
    token_id = 1
    contract_address = "0x250A2aeb3eB84782e83365b4c42dbE3CDA9920e4"
    request, _ = contract_api_dialogues.create(
        counterparty=str(ledger_apis_connection.connection_id),
        performative=ContractApiMessage.Performative.GET_STATE,
        ledger_id=ETHEREUM,
        contract_id=str(ERC1155_PUBLIC_ID),
        contract_address=contract_address,
        callable="unknown_callable",
        kwargs=ContractApiMessage.Kwargs({
            "agent_address": address,
            "token_id": token_id
        }),
    )
    envelope = Envelope(
        to=request.to,
        sender=request.sender,
        protocol_id=request.protocol_id,
        message=request,
    )

    with caplog.at_level(logging.DEBUG,
                         "aea.packages.fetchai.connections.ledger"):
        await ledger_apis_connection.send(envelope)
        await asyncio.sleep(0.01)
        assert f"Cannot find {request.callable} in contract" in caplog.text
예제 #20
0
async def test_callable_wrong_number_of_arguments_apis_method_call(
        erc1155_contract, ledger_apis_connection, caplog):
    """
    Test a contract callable with wrong number of arguments.

    Test the case of either GET_DEPLOY_TRANSACTION.
    """
    address = ETHEREUM_ADDRESS_ONE
    contract_api_dialogues = ContractApiDialogues(address)
    request, _ = contract_api_dialogues.create(
        counterparty=str(ledger_apis_connection.connection_id),
        performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION,
        ledger_id=ETHEREUM,
        contract_id=str(ERC1155_PUBLIC_ID),
        callable="get_deploy_transaction",
        kwargs=ContractApiMessage.Kwargs({}),
    )
    envelope = Envelope(
        to=request.to,
        sender=request.sender,
        protocol_id=request.protocol_id,
        message=request,
    )

    with unittest.mock.patch.object(
            ledger_apis_connection._contract_dispatcher,
            "_call_stub",
            return_value=None):
        with caplog.at_level(logging.DEBUG,
                             "aea.packages.fetchai.connections.ledger"):
            await ledger_apis_connection.send(envelope)
            await asyncio.sleep(0.01)
            assert (
                "An error occurred while processing the contract api request: 'get_deploy_transaction() missing 1 required positional argument: 'deployer_address''."
                in caplog.text)
    def _request_contract_state(self, contract_name: str, callable_: str,
                                parameters: dict) -> None:
        """
        Request contract deploy transaction

        :return: None
        """
        params = {"deployer_address": self.context.agent_address}
        params.update(parameters)
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_price_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_STATE,
            ledger_id=strategy.ledger_id,
            contract_id=f"eightballer/{contract_name}:0.1.0",
            contract_address=strategy.get_contract_address(contract_name),
            callable=callable_,
            kwargs=ContractApiMessage.Kwargs(params),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_deploy_terms()
        strategy.set_status(
            contract_name,
            callable_,
            contract_api_dialogue.dialogue_label.dialogue_reference[0],
        )
        self.context.outbox.put_message(message=contract_api_msg)
예제 #22
0
async def test_erc1155_get_deploy_transaction(erc1155_contract, ledger_apis_connection):
    """Test get state with contract erc1155."""
    address = ETHEREUM_ADDRESS_ONE
    contract_api_dialogues = ContractApiDialogues(address)
    request, contract_api_dialogue = contract_api_dialogues.create(
        counterparty=str(ledger_apis_connection.connection_id),
        performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION,
        ledger_id=ETHEREUM,
        contract_id=str(ERC1155_PUBLIC_ID),
        callable="get_deploy_transaction",
        kwargs=ContractApiMessage.Kwargs({"deployer_address": address}),
    )
    envelope = Envelope(to=request.to, sender=request.sender, 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) == ContractApiMessage
    response_message = cast(ContractApiMessage, response.message)
    assert (
        response_message.performative == ContractApiMessage.Performative.RAW_TRANSACTION
    ), "Error: {}".format(response_message.message)
    response_dialogue = contract_api_dialogues.update(response_message)
    assert response_dialogue == contract_api_dialogue
    assert type(response_message.raw_transaction) == RawTransaction
    assert response_message.raw_transaction.ledger_id == ETHEREUM
    assert len(response.message.raw_transaction.body) == 6
    assert len(response.message.raw_transaction.body["data"]) > 0
예제 #23
0
    def _request_contract_deploy_transaction(self) -> None:
        """
        Request contract deploy transaction

        :return: None
        """
        parameters = cast(Parameters, self.context.parameters)
        contract_api_dialogues = cast(
            ContractApiDialogues, self.context.contract_api_dialogues
        )
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION,
            ledger_id=parameters.ledger_id,
            contract_id=parameters.contract_id,
            callable=ContractApiDialogue.Callable.GET_DEPLOY_TRANSACTION.value,
            kwargs=ContractApiMessage.Kwargs(
                {"deployer_address": self.context.agent_address, "gas": parameters.gas}
            ),
        )
        contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue,)
        contract_api_dialogue.terms = parameters.get_deploy_terms()
        contract_api_dialogue.callable = (
            ContractApiDialogue.Callable.GET_DEPLOY_TRANSACTION
        )
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting contract deployment transaction...")
예제 #24
0
    def _request_approve_transaction(self) -> None:
        """
        Request transaction that approves client contract to spend tokens on behalf of sender

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=str(LEDGER_API_ADDRESS),
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=str(FET_ERC20_PUBLIC_ID),
            contract_address=strategy.erc20_address,
            callable="get_approve_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "from_address":
                self.context.agent_address,
                "spender":
                strategy.client_contract_address,
                "amount":
                strategy.approve_amount,
                "gas":
                strategy.default_gas_approve,
            }),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_approve_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting query transaction...")
예제 #25
0
async def test_callable_generic_error(erc1155_contract, ledger_apis_connection):
    """Test error messages when an exception is raised while processing the request."""
    contract, contract_address = erc1155_contract
    address = ETHEREUM_ADDRESS_ONE
    contract_api_dialogues = ContractApiDialogues(address)
    token_id = 1
    request, _ = contract_api_dialogues.create(
        counterparty=str(ledger_apis_connection.connection_id),
        performative=ContractApiMessage.Performative.GET_STATE,
        ledger_id=ETHEREUM,
        contract_id=str(ERC1155_PUBLIC_ID),
        contract_address=contract_address,
        callable="get_balance",
        kwargs=ContractApiMessage.Kwargs(
            {"agent_address": address, "token_id": token_id}
        ),
    )
    envelope = Envelope(to=request.to, sender=request.sender, message=request,)

    with unittest.mock.patch(
        "inspect.getfullargspec", side_effect=Exception("Generic error")
    ):
        with unittest.mock.patch.object(
            ledger_apis_connection._logger, "error"
        ) as mock_logger:
            await ledger_apis_connection.send(envelope)
            await asyncio.sleep(0.01)
            response = await ledger_apis_connection.receive()
            mock_logger.assert_any_call(
                "An error occurred while processing the contract api request: 'Generic error'."
            )
            assert (
                response.message.performative == ContractApiMessage.Performative.ERROR
            )
            assert response.message.message == "Generic error"
예제 #26
0
    def _request_update_transaction(self, update_args: Dict[str, Any]) -> None:
        """
        Request transaction that updates value in Fetch oracle contract

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        strategy.is_behaviour_active = False
        contract_api_dialogues = cast(ContractApiDialogues,
                                      self.context.contract_api_dialogues)
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=str(LEDGER_API_ADDRESS),
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=strategy.ledger_id,
            contract_id=str(CONTRACT_PUBLIC_ID),
            contract_address=strategy.contract_address,
            callable="get_update_transaction",
            kwargs=ContractApiMessage.Kwargs({
                "oracle_address":
                self.context.agent_address,
                "update_function":
                strategy.update_function,
                "update_args":
                list(update_args.values()),
                "gas":
                strategy.default_gas_update,
            }),
        )
        contract_api_dialogue = cast(ContractApiDialogue,
                                     contract_api_dialogue)
        contract_api_dialogue.terms = strategy.get_update_terms()
        self.context.outbox.put_message(message=contract_api_msg)
        self.context.logger.info("requesting update transaction...")
예제 #27
0
    def _handle_accept_w_inform(
        self, fipa_msg: FipaMessage, fipa_dialogue: FipaDialogue
    ) -> None:
        """
        Handle the ACCEPT_W_INFORM.

        If the ACCEPT_W_INFORM message contains the signed transaction, sign it too, otherwise do nothing.

        :param fipa_msg: the message
        :param fipa_dialogue: the dialogue object
        :return: None
        """
        tx_signature = fipa_msg.info.get("tx_signature", None)
        if tx_signature is not None:
            self.context.logger.info(
                "received ACCEPT_W_INFORM from sender={}: tx_signature={}".format(
                    fipa_msg.sender[-5:], tx_signature
                )
            )
            strategy = cast(Strategy, self.context.strategy)
            contract_api_dialogues = cast(
                ContractApiDialogues, self.context.contract_api_dialogues
            )
            contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
                counterparty=LEDGER_API_ADDRESS,
                performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
                ledger_id=strategy.ledger_id,
                contract_id=strategy.contract_id,
                contract_address=strategy.contract_address,
                callable="get_atomic_swap_single_transaction",
                kwargs=ContractApiMessage.Kwargs(
                    {
                        "from_address": self.context.agent_address,
                        "to_address": fipa_msg.sender,
                        "token_id": int(fipa_dialogue.proposal.values["token_id"]),
                        "from_supply": int(
                            fipa_dialogue.proposal.values["from_supply"]
                        ),
                        "to_supply": int(fipa_dialogue.proposal.values["to_supply"]),
                        "value": int(fipa_dialogue.proposal.values["value"]),
                        "trade_nonce": int(
                            fipa_dialogue.proposal.values["trade_nonce"]
                        ),
                        "signature": tx_signature,
                    }
                ),
            )
            contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
            contract_api_dialogue.terms = strategy.get_single_swap_terms(
                fipa_dialogue.proposal, fipa_msg.sender
            )
            self.context.outbox.put_message(message=contract_api_msg)
            self.context.logger.info("requesting single atomic swap transaction...")
        else:
            self.context.logger.info(
                "received ACCEPT_W_INFORM from sender={} with no signature.".format(
                    fipa_msg.sender[-5:]
                )
            )
예제 #28
0
    def _handle_register(
        self, register_msg: RegisterMessage, register_dialogue: RegisterDialogue
    ) -> None:
        """
        Handle an register message.

        :param register_msg: the register message
        :param register_dialogue: the dialogue
        :return: None
        """
        self.context.logger.info(
            f"received register_msg register message={register_msg} in dialogue={register_dialogue}."
        )
        strategy = cast(Strategy, self.context.strategy)
        is_valid, error_code, error_msg = strategy.valid_registration(
            register_msg.info, register_msg.sender
        )
        if is_valid:
            strategy.lock_registration_temporarily(
                register_msg.sender, register_msg.info
            )
            self.context.logger.info(
                f"valid registration={register_msg.info}. Verifying if tokens staked."
            )
            contract_api_dialogues = cast(
                ContractApiDialogues, self.context.contract_api_dialogues
            )
            kwargs = strategy.get_kwargs(register_msg.info)
            terms = strategy.get_terms(register_msg.sender)
            contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
                counterparty=LEDGER_API_ADDRESS,
                performative=ContractApiMessage.Performative.GET_STATE,
                ledger_id=strategy.contract_ledger_id,
                contract_id=strategy.contract_id,
                contract_address=strategy.contract_address,
                callable=strategy.contract_callable,
                kwargs=ContractApiMessage.Kwargs(kwargs),
            )
            contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
            contract_api_dialogue.terms = terms
            contract_api_dialogue.associated_register_dialogue = register_dialogue
            self.context.outbox.put_message(contract_api_msg)
        else:
            self.context.logger.info(
                f"invalid registration={register_msg.info}. Rejecting."
            )
            reply = register_dialogue.reply(
                performative=RegisterMessage.Performative.ERROR,
                error_code=error_code,
                error_msg=error_msg,
                info={},
            )
            self.context.outbox.put_message(reply)
예제 #29
0
    def test_handle_raw_transaction(self, ):
        """Test the _handle_signed_transaction method of the signing handler."""
        # setup
        contract_api_dialogue = cast(
            ContractApiDialogue,
            self.prepare_skill_dialogue(
                dialogues=self.contract_api_dialogues,
                messages=self.list_of_contract_api_messages[:1],
            ),
        )
        contract_api_dialogue.terms = Terms(
            "some_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=contract_api_dialogue,
            performative=ContractApiMessage.Performative.RAW_TRANSACTION,
            raw_transaction=ContractApiMessage.RawTransaction(
                "some_ledger_id", {"some_key": "some_value"}),
        )

        # operation
        with patch.object(self.logger, "log") as mock_logger:
            self.contract_api_handler.handle(incoming_message)

        # after
        mock_logger.assert_any_call(
            logging.INFO, f"received raw transaction={incoming_message}")

        self.assert_quantity_in_decision_making_queue(1)
        message = self.get_message_from_decision_maker_inbox()
        has_attributes, error_str = self.message_has_attributes(
            actual_message=message,
            message_type=SigningMessage,
            performative=SigningMessage.Performative.SIGN_TRANSACTION,
            to=self.skill.skill_context.decision_maker_address,
            sender=str(self.skill.skill_context.skill_id),
            terms=contract_api_dialogue.terms,
        )
        assert has_attributes, error_str

        assert (cast(SigningDialogue,
                     self.signing_dialogues.get_dialogue(message)).
                associated_contract_api_dialogue == contract_api_dialogue)

        mock_logger.assert_any_call(
            logging.INFO,
            "proposing the transaction to the decision maker. Waiting for confirmation ...",
        )
예제 #30
0
    def _request_mint_items_transaction(self, game: Game) -> None:
        """
        Request token mint transaction

        :return: None
        """
        if not game.is_allowed_to_mint:
            return
        game.is_allowed_to_mint = False
        agent_state = game.get_next_agent_state_for_minting()
        if agent_state is None:
            return
        name = game.registration.agent_addr_to_name[agent_state.agent_address]
        self.context.logger.info(
            f"requesting mint_items transactions for agent={name}."
        )
        parameters = cast(Parameters, self.context.parameters)
        token_ids = []  # type: List[int]
        mint_quantities = []  # type: List[int]
        for good_id, quantity in agent_state.quantities_by_good_id.items():
            token_ids.append(int(good_id))
            mint_quantities.append(quantity)
        for currency_id, amount in agent_state.amount_by_currency_id.items():
            token_ids.append(int(currency_id))
            mint_quantities.append(amount)
        contract_api_dialogues = cast(
            ContractApiDialogues, self.context.contract_api_dialogues
        )
        contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
            counterparty=LEDGER_API_ADDRESS,
            performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
            ledger_id=parameters.ledger_id,
            contract_id=parameters.contract_id,
            contract_address=parameters.contract_address,
            callable=ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION.value,
            kwargs=ContractApiMessage.Kwargs(
                {
                    "deployer_address": self.context.agent_address,
                    "recipient_address": self.context.agent_address,
                    "token_ids": token_ids,
                    "mint_quantities": mint_quantities,
                    "gas": parameters.gas,
                }
            ),
        )
        contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
        contract_api_dialogue.terms = parameters.get_mint_token_terms()
        contract_api_dialogue.callable = (
            ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
        )
        self.context.outbox.put_message(message=contract_api_msg)