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
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
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
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))
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
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
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)
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")
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)
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...")
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...")
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...")
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...")
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...")
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
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)
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...")
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...")
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
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)
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
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...")
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...")
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"
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...")
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:] ) )
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)
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 ...", )
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)