def test_decision_maker_handle_tx_message_not_ready(self): """Test that the decision maker is not ready to pursuit the goals.Cannot handle the message.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info=self.info, ledger_id=self.ledger_id, tx_nonce="Transaction nonce", ) with mock.patch.object( self.decision_maker_handler.context.ledger_apis, "token_balance", return_value=1000000, ): with mock.patch.object( self.decision_maker_handler.context.ledger_apis, "transfer", return_value="This is a test digest", ): with mock.patch( "aea.decision_maker.default.GoalPursuitReadiness.Status" ) as mocked_status: mocked_status.READY.value = False self.decision_maker.handle(tx_message) assert (not self.decision_maker_handler.context. goal_pursuit_readiness.is_ready) self.decision_maker.message_out_queue.get() tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info=self.info, ledger_id=self.ledger_id, tx_nonce="transaction nonce", ) self.decision_maker.handle(tx_message) assert not self.decision_maker.message_out_queue.empty() self.decision_maker.message_out_queue.get()
def test_transaction_is_affordable_agent_is_buyer(): """Check if the agent has the money to cover the sender_amount (the agent=sender is the buyer).""" currency_endowment = {"FET": 100} good_endowment = {"good_id": 20} ownership_state = OwnershipState() ownership_state.set( amount_by_currency_id=currency_endowment, quantities_by_good_id=good_endowment, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": -1}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) assert ownership_state.is_affordable_transaction( tx_message=tx_message), "We should have the money for the transaction!"
def test_transaction_update_receive(): """Test the transaction update when receiving tokens.""" currency_endowment = {"FET": 75} good_endowment = {"good_id": 30} ownership_state = OwnershipState() ownership_state.set( amount_by_currency_id=currency_endowment, quantities_by_good_id=good_endowment, ) assert ownership_state.amount_by_currency_id == currency_endowment assert ownership_state.quantities_by_good_id == good_endowment tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": 20}, tx_sender_fee=5, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": -10}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) ownership_state._update(tx_message=tx_message) expected_amount_by_currency_id = {"FET": 90} expected_quantities_by_good_id = {"good_id": 20} assert ownership_state.amount_by_currency_id == expected_amount_by_currency_id assert ownership_state.quantities_by_good_id == expected_quantities_by_good_id
def test_apply(): """Test the apply function.""" currency_endowment = {"FET": 100} good_endowment = {"good_id": 2} ownership_state = OwnershipState() ownership_state.set( amount_by_currency_id=currency_endowment, quantities_by_good_id=good_endowment, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=5, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) list_of_transactions = [tx_message] state = ownership_state new_state = ownership_state.apply_transactions( transactions=list_of_transactions) assert ( state != new_state ), "after applying a list_of_transactions must have a different state!"
def tests_transaction_is_affordable_else_statement(): """Check that the function returns false if we cannot satisfy any if/elif statements.""" currency_endowment = {"FET": 0} good_endowment = {"good_id": 0} ownership_state = OwnershipState() ownership_state.set( amount_by_currency_id=currency_endowment, quantities_by_good_id=good_endowment, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": 10}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 50}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) assert not ownership_state.is_affordable_transaction( tx_message=tx_message), "We must reject the transaction."
def test_transaction_is_affordable_there_is_no_wealth(): """Reject the transaction when there is no wealth exchange.""" currency_endowment = {"FET": 0} good_endowment = {"good_id": 0} ownership_state = OwnershipState() ownership_state.set( amount_by_currency_id=currency_endowment, quantities_by_good_id=good_endowment, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": 0}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 0}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) assert not ownership_state.is_affordable_transaction( tx_message=tx_message), "We must reject the transaction."
def test_handle_internal_messages(self): """Test that the internal messages are handled.""" t = TransactionMessage( performative=TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT, tx_id="transaction0", skill_callback_ids=[PublicId("dummy_author", "dummy", "0.1.0")], tx_sender_addr="pk1", tx_counterparty_addr="pk2", tx_amount_by_currency_id={"FET": 2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"Unknown": 10}, ledger_id="fetchai", info={}, tx_digest="some_tx_digest", ) self.aea.decision_maker.message_out_queue.put(t) self.aea._filter.handle_internal_messages() internal_handlers_list = self.aea.resources.get_handlers( PublicId("fetchai", "internal", "0.1.0")) assert len(internal_handlers_list) == 1 internal_handler = internal_handlers_list[0] assert len(internal_handler.handled_internal_messages) == 1 self.aea.teardown()
def test_settle_tx_known_chain(self): """Test the off_chain message.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, ledger_id=self.ledger_id, info=self.info, tx_nonce="Transaction nonce", ) with mock.patch.object( self.decision_maker_handler.context.ledger_apis, "transfer", return_value="tx_digest", ): tx_digest = self.decision_maker_handler._settle_tx(tx_message) assert tx_digest == "tx_digest"
def test_decision_maker_handle_unknown_tx_message(self): """Test the handle tx message method.""" patch_logger_error = mock.patch.object( aea.decision_maker.default.logger, "error") mocked_logger_error = patch_logger_error.__enter__() with mock.patch( "aea.decision_maker.messages.transaction.TransactionMessage._is_consistent", return_value=True, ): tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info=self.info, ledger_id="bitcoin", ) self.decision_maker.handle(tx_message) mocked_logger_error.assert_called_with( "[test]: ledger_id=bitcoin is not supported")
def test_respond_message(self): tx_hash = Web3.keccak(text="some_bytes") tx_signature = Web3.keccak(text="tx_signature") tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 0}, ledger_id=self.ledger_id, info=self.info, signing_payload={"tx_hash": tx_hash}, ) tx_message_response = TransactionMessage.respond_signing( tx_message, performative=TransactionMessage.Performative.SUCCESSFUL_SIGNING, signed_payload={"tx_signature": tx_signature}, ) assert tx_message_response.signed_payload.get( "tx_signature") == tx_signature
def test_decision_maker_tx_message_is_not_acceptable_for_settlement(self): """Test that a tx_message is not acceptable for settlement.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, ledger_id=self.ledger_id, info=self.info, tx_nonce="Transaction nonce", ) with mock.patch.object( self.decision_maker_handler, "_is_acceptable_for_settlement", return_value=True, ): with mock.patch.object(self.decision_maker_handler, "_settle_tx", return_value=None): self.decision_maker.handle(tx_message) assert not self.decision_maker.message_out_queue.empty() self.decision_maker.message_out_queue.get()
def _handle_match_accept(self, msg: FipaMessage, dialogue: Dialogue) -> None: """ Handle the match accept. :param msg: the message :param dialogue: the dialogue object :return: None """ strategy = cast(Strategy, self.context.strategy) if strategy.is_ledger_tx: self.context.logger.info( "[{}]: received MATCH_ACCEPT_W_INFORM from sender={}".format( self.context.agent_name, msg.counterparty[-5:])) info = msg.info address = cast(str, info.get("address")) proposal = cast(Description, dialogue.proposal) strategy = cast(Strategy, self.context.strategy) tx_msg = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[ PublicId("fetchai", "carpark_client", "0.1.0") ], tx_id="transaction0", tx_sender_addr=self.context.agent_addresses["fetchai"], tx_counterparty_addr=address, tx_amount_by_currency_id={ proposal.values["currency_id"]: -proposal.values["price"] }, tx_sender_fee=strategy.max_buyer_tx_fee, tx_counterparty_fee=proposal.values["seller_tx_fee"], tx_quantities_by_good_id={}, ledger_id=proposal.values["ledger_id"], info={"dialogue_label": dialogue.dialogue_label.json}, ) self.context.decision_maker_message_queue.put_nowait(tx_msg) self.context.logger.info( "[{}]: proposing the transaction to the decision maker. Waiting for confirmation ..." .format(self.context.agent_name)) else: new_message_id = msg.message_id + 1 new_target = msg.message_id inform_msg = FipaMessage( message_id=new_message_id, dialogue_reference=dialogue.dialogue_label.dialogue_reference, target=new_target, performative=FipaMessage.Performative.INFORM, info={"Done": "Sending payment via bank transfer"}, ) dialogue.outgoing_extend(inform_msg) self.context.outbox.put_message( to=msg.counterparty, sender=self.context.agent_address, protocol_id=FipaMessage.protocol_id, message=FipaSerializer().encode(inform_msg), ) self.context.logger.info( "[{}]: informing counterparty={} of payment.".format( self.context.agent_name, msg.counterparty[-5:]))
def test_decision_maker_execute(self): """Test the execute method.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info=self.info, ledger_id=self.ledger_id, tx_nonce="Transaction nonce", ) self.decision_maker.message_in_queue.put_nowait(tx_message) # test that after a while the queue has been consumed. time.sleep(0.5) assert self.decision_maker.message_in_queue.empty() time.sleep(0.5) assert not self.decision_maker.message_out_queue.empty() # TODO test the content of the response. response = self.decision_maker.message_out_queue.get() # noqa
def test_decision_maker_handle_tx_message(self): """Test the handle tx message method.""" assert self.decision_maker.message_out_queue.empty() tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, info=self.info, ledger_id=self.ledger_id, tx_nonce="Transaction nonce", ) with mock.patch.object( self.decision_maker_handler.context.ledger_apis, "token_balance", return_value=1000000, ): with mock.patch.object( self.decision_maker_handler.context.ledger_apis, "transfer", return_value="This is a test digest", ): self.decision_maker.handle(tx_message) assert not self.decision_maker.message_out_queue.empty() self.decision_maker.message_out_queue.get()
def _handle_match_accept(self, msg: FIPAMessage, sender: str, message_id: int, dialogue: Dialogue) -> None: """ Handle the match accept. :param msg: the message :param sender: the sender :param message_id: the message id :param dialogue: the dialogue object :return: None """ logger.info( "[{}]: received MATCH_ACCEPT_W_ADDRESS from sender={}".format( self.context.agent_name, sender[-5:])) address = cast(str, msg.get("address")) proposal = cast(Description, dialogue.proposal) tx_msg = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE, skill_id="carpark_client", transaction_id="transaction0", sender=self.context.agent_public_keys['fetchai'], counterparty=address, is_sender_buyer=True, currency_pbk="FET", amount=proposal.values['price'], sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={}, dialogue_label=dialogue.dialogue_label.json, ledger_id='fetchai') self.context.decision_maker_message_queue.put_nowait(tx_msg) logger.info( "[{}]: proposing the transaction to the decision maker. Waiting for confirmation ..." .format(self.context.agent_name))
def test_is_affordable_ledger_state_proxy(self): """Test that the tx_message is affordable with initialized ledger_state_proxy.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, ledger_id=self.ledger_id, info=self.info, tx_nonce="Transaction nonce", ) with mock.patch.object( self.decision_maker_handler, "_is_acceptable_for_settlement", return_value=True, ): with mock.patch.object(self.decision_maker_handler, "_settle_tx", return_value="tx_digest"): self.decision_maker_handler._is_affordable(tx_message)
def test_message_consistency(self): """Test for an error in consistency of a message.""" assert TransactionMessage( performative=TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT, skill_callback_ids=[PublicId.from_str("author/skill:0.1.0")], tx_id="transaction0", tx_sender_addr="pk1", tx_counterparty_addr="pk2", tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"GOOD_ID": 10}, ledger_id="fetchai", info={"some_string": [1, 2]}, tx_digest="some_string", ) with pytest.raises(AssertionError): TransactionMessage( performative=TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT, skill_callback_ids=[PublicId.from_str("author/skill:0.1.0")], tx_id="transaction0", tx_sender_addr="pk1", tx_counterparty_addr="pk2", tx_amount_by_currency_id={"FET": -2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"GOOD_ID": 10}, ledger_id="ethereum", info={"some_string": [1, 2]}, tx_digest="some_string", ) with pytest.raises(AssertionError): TransactionMessage( performative=TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT, skill_callback_ids=[PublicId.from_str("author/skill:0.1.0")], tx_id="transaction0", tx_sender_addr="pk", tx_counterparty_addr="pk", tx_amount_by_currency_id={"Unknown": 2}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"Unknown": 10}, ledger_id="fetchai", info={"info": "info_value"}, )
def get_mint_single_transaction_msg( self, deployer_address: Address, recipient_address: Address, token_id: int, mint_quantity: int, ledger_api: LedgerApi, skill_callback_id: ContractId, transaction_id: str = Performative.CONTRACT_MINT_SINGLE.value, info: Optional[Dict[str, Any]] = None, ) -> TransactionMessage: """ Get the transaction message containing the transaction to mint a batch of tokens. :param deployer_address: the deployer_address :param recipient_address: the recipient_address :param token_id: the token id :param mint_quantity: the mint_quantity of each token :param ledger_api: the ledger api :param skill_callback_id: the skill callback id :param transaction_id: the transaction id :param info: the optional info payload for the transaction message :return: the transaction message for the decision maker """ tx = self.get_mint_single_transaction( deployer_address=deployer_address, recipient_address=recipient_address, token_id=token_id, mint_quantity=mint_quantity, ledger_api=ledger_api, ) logger.debug( "get_mint_single_tx: deployer_address={}, recipient_address={}, token_id={}, mint_quantity={}, tx={}" .format( deployer_address, recipient_address, token_id, mint_quantity, tx, )) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[skill_callback_id], tx_id=transaction_id, tx_sender_addr=deployer_address, tx_counterparty_addr=recipient_address, tx_amount_by_currency_id={ETHEREUM_CURRENCY: 0}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={str(token_id): mint_quantity}, info=info if info is not None else {}, ledger_id=EthereumCrypto.identifier, signing_payload={"tx": tx}, ) return tx_message
def test_transaction_update(self): """Test the tranasction update.""" currency_endowment = {"FET": 100} good_endowment = {"good_pbk": 2} self.ownership_state.init(amount_by_currency=currency_endowment, quantities_by_good_pbk=good_endowment) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE, skill_id="default", transaction_id="transaction0", sender="agent_1", counterparty="pk", is_sender_buyer=True, currency_pbk="FET", amount=20, sender_tx_fee=5, counterparty_tx_fee=0, quantities_by_good_pbk={"good_pbk": 10}, ledger_id="fetchai") cur_holdings = self.ownership_state.amount_by_currency['FET'] self.ownership_state.update(tx_message=tx_message) assert self.ownership_state.amount_by_currency['FET'] < cur_holdings tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE, skill_id="default", transaction_id="transaction0", sender="agent_1", counterparty="pk", is_sender_buyer=False, currency_pbk="FET", amount=20, sender_tx_fee=5, counterparty_tx_fee=0, quantities_by_good_pbk={"good_pbk": 10}, ledger_id="fetchai") cur_holdings = self.ownership_state.amount_by_currency['FET'] self.ownership_state.update(tx_message=tx_message) assert self.ownership_state.amount_by_currency['FET'] > cur_holdings
def test_transaction_is_consistent(self): """Test the consistency of the transaction message.""" currency_endowment = {"FET": 100} good_endowment = {"good_pbk": 2} self.ownership_state.init(amount_by_currency=currency_endowment, quantities_by_good_pbk=good_endowment) tx_message = TransactionMessage( performative=TransactionMessage.Performative.ACCEPT, skill_id="default", transaction_id="transaction0", sender="agent_1", counterparty="pk", is_sender_buyer=True, currency_pbk="FET", amount=1, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"good_pbk": 10}, ledger_id="fetchai") assert self.ownership_state.check_transaction_is_consistent(tx_message=tx_message),\ "We should have the money for the transaction!" tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE, skill_id="default", transaction_id="transaction0", sender="agent_1", counterparty="pk", is_sender_buyer=False, currency_pbk="FET", amount=1, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"good_pbk": 10}, ledger_id="fetchai") assert self.ownership_state.check_transaction_is_consistent(tx_message=tx_message), \ "We should have the money for the transaction!"
def get_mint_batch_transaction( self, deployer_address: Address, recipient_address: Address, token_ids: List[int], mint_quantities: List[int], ledger_api: LedgerApi, skill_callback_id: ContractId, info: Optional[Dict[str, Any]] = None, ) -> TransactionMessage: """ Mint a batch of tokens. :param deployer_address: the deployer_address :param recipient_address: the recipient_address :param token_ids: the token ids :param mint_quantities: the mint_quantities of each token :param ledger_api: the ledger api :param skill_callback_id: the skill callback id :param info: the optional info payload for the transaction message :return: the transaction message for the decision maker """ assert len(mint_quantities) == len(token_ids), "Wrong number of items." tx = self._create_mint_batch_tx( deployer_address=deployer_address, recipient_address=recipient_address, token_ids=token_ids, mint_quantities=mint_quantities, ledger_api=ledger_api, ) logger.debug( "get_mint_batch_transaction: deployer_address={}, recipient_address={}, token_ids={}, mint_quantities={}, tx={}".format( deployer_address, recipient_address, token_ids, mint_quantities, tx, ) ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[skill_callback_id], tx_id=ERC1155Contract.Performative.CONTRACT_MINT_BATCH.value, tx_sender_addr=deployer_address, tx_counterparty_addr="", tx_amount_by_currency_id={"ETH": 0}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={}, info=info if info is not None else {}, ledger_id=ETHEREUM, signing_payload={"tx": tx}, ) return tx_message
def get_mint_single_tx( self, deployer_address: Address, recipient_address: Address, token_id: int, mint_quantity: int, ledger_api: LedgerApi, skill_callback_id: ContractId, info: Optional[Dict[str, Any]] = None, ) -> TransactionMessage: """ Mint a single token. :param deployer_address: the deployer_address :param recipient_address: the recipient_address :param token_id: the token id :param mint_quantity: the mint_quantity of each token :param ledger_api: the ledger api :param skill_callback_id: the skill callback id :param info: the optional info payload for the transaction message :return: the transaction message for the decision maker """ tx = self._create_mint_single_tx( deployer_address=deployer_address, recipient_address=recipient_address, token_id=token_id, mint_quantity=mint_quantity, ledger_api=ledger_api, ) logger.debug( "get_mint_single_tx: deployer_address={}, recipient_address={}, token_id={}, mint_quantity={}, tx={}".format( deployer_address, recipient_address, token_id, mint_quantity, tx, ) ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[skill_callback_id], tx_id="contract_mint_batch", tx_sender_addr=deployer_address, tx_counterparty_addr="", tx_amount_by_currency_id={"ETH": 0}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={}, info=info if info is not None else {}, ledger_id=ETHEREUM, signing_payload={"tx": tx}, ) return tx_message
def test_matches(self): """Test if the transaction matches with another transaction.""" msg = TransactionMessage( performative=TransactionMessage.Performative.ACCEPT, skill_id="default", transaction_id="transaction0", sender="agent_1", counterparty="pk", is_sender_buyer=True, currency_pbk="FET", amount=2, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"FET": 10}, ledger_id="fetchai") assert not msg.matches( msg), "It shouldn't match since it is the same message." assert msg == msg, "It should be equal since is the same message." mirrored_message = TransactionMessage( performative=TransactionMessage.Performative.ACCEPT, skill_id="default", transaction_id="transaction0", sender="pk", counterparty="agent_1", is_sender_buyer=False, currency_pbk="FET", amount=2, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"FET": 10}, ledger_id="fetchai") assert msg.matches( mirrored_message ), "It should match since the messages mirror each other"
def test_message_consistency(self): """Test for an error in consistency of a message.""" with pytest.raises(AssertionError): TransactionMessage(performative="performative", skill_id="default", transaction_id="transaction0", sender="pk", counterparty="pk", is_sender_buyer=True, currency_pbk="Unknown", amount=2, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"Unknown": 10}, ledger_id="fetchai")
def get_create_single_transaction_msg( self, deployer_address: Address, token_id: int, ledger_api: LedgerApi, skill_callback_id: ContractId, transaction_id: str = Performative.CONTRACT_CREATE_SINGLE.value, info: Optional[Dict[str, Any]] = None, ) -> TransactionMessage: """ Get the transaction message containing the transaction to create a single token. :param deployer_address: the address of the deployer (owner) :param token_id: the token id for creation :param ledger_api: the ledger API :param skill_callback_id: the skill callback id :param transaction_id: the transaction id :param info: optional info to pass with the transaction message :return: the transaction message for the decision maker """ tx = self.get_create_single_transaction( deployer_address=deployer_address, token_id=token_id, ledger_api=ledger_api, ) logger.debug( "get_create_single_transaction: deployer_address={}, token_id={}, tx={}" .format( deployer_address, token_id, tx, )) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[skill_callback_id], tx_id=transaction_id, tx_sender_addr=deployer_address, tx_counterparty_addr=deployer_address, tx_amount_by_currency_id={ETHEREUM_CURRENCY: 0}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={}, info=info if info is not None else {}, ledger_id=EthereumCrypto.identifier, signing_payload={"tx": tx}, ) return tx_message
def test_score_diff_from_transaction(): """Test the difference between the scores.""" good_holdings = {"good_id": 2} currency_holdings = {"FET": 100} utility_params = {"good_id": 20.0} exchange_params = {"FET": 10.0} tx_fee = 3 ownership_state = OwnershipState() ownership_state.set(amount_by_currency_id=currency_holdings, quantities_by_good_id=good_holdings) preferences = Preferences() preferences.set( utility_params_by_good_id=utility_params, exchange_params_by_currency_id=exchange_params, tx_fee=tx_fee, ) tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id="transaction0", tx_sender_addr="agent_1", tx_counterparty_addr="pk", tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=preferences.seller_transaction_fee, tx_counterparty_fee=preferences.buyer_transaction_fee, tx_quantities_by_good_id={"good_id": 10}, info={"some_info_key": "some_info_value"}, ledger_id="fetchai", tx_nonce="transaction nonce", ) cur_score = preferences.utility(quantities_by_good_id=good_holdings, amount_by_currency_id=currency_holdings) new_state = ownership_state.apply_transactions([tx_message]) new_score = preferences.utility( quantities_by_good_id=new_state.quantities_by_good_id, amount_by_currency_id=new_state.amount_by_currency_id, ) dif_scores = new_score - cur_score score_difference = preferences.utility_diff_from_transaction( ownership_state=ownership_state, tx_message=tx_message) assert ( score_difference == dif_scores ), "The calculated difference must be equal to the return difference from the function."
def test_handle_internal_messages(self): """Test that the internal messages are handled.""" self.aea.setup() t = TransactionMessage(performative=TransactionMessage.Performative.ACCEPT, skill_id="dummy", transaction_id="transaction0", sender="pk1", counterparty="pk2", is_sender_buyer=True, currency_pbk="Unknown", amount=2, sender_tx_fee=0, counterparty_tx_fee=0, quantities_by_good_pbk={"Unknown": 10}) self.aea.decision_maker.message_out_queue.put(t) self.aea.filter.handle_internal_messages() internal_handler = self.aea.resources.handler_registry.fetch_by_skill("internal", "dummy") assert len(internal_handler.handled_internal_messages) == 1
def _on_propose(self, propose: FIPAMessage, dialogue: Dialogue) -> None: """ Handle a Propose. :param propose: the message containing the Propose :param dialogue: the dialogue :return: None """ logger.debug("[{}]: on propose as {}.".format(self.context.agent_name, dialogue.role)) proposals = cast(List[Description], propose.get("proposal")) for num, proposal_description in enumerate(proposals): if num > 0: continue # TODO: allow for dialogue branching with multiple proposals transaction_id = generate_transaction_id(self.context.agent_public_key, dialogue.dialogue_label.dialogue_opponent_pbk, dialogue.dialogue_label, dialogue.is_seller) transaction_msg = TransactionMessage(transaction_id=transaction_id, sender=self.context.agent_public_key, counterparty=dialogue.dialogue_label.dialogue_opponent_pbk, currency='FET', amount=proposal_description.values['amount'], is_sender_buyer=not dialogue.is_seller, sender_tx_fee=1, counterparty_tx_fee=1, quantities_by_good_pbk=proposal_description.values['description']) new_msg_id = cast(int, propose.get("id")) + 1 strategy = cast(Strategy, self.context.strategy) transactions = cast(Transactions, self.context.transactions) ownership_state_after_locks = transactions.ownership_state_after_locks(self.context.ownership_state, is_seller=dialogue.is_seller) if strategy.is_profitable_transaction(self.context.preferences, ownership_state_after_locks, transaction_msg): logger.debug("[{}]: Accepting propose (as {}).".format(self.context.agent_name, dialogue.role)) transactions.add_locked_tx(transaction_msg, as_seller=dialogue.is_seller) transactions.add_pending_initial_acceptance(dialogue.dialogue_label, new_msg_id, transaction_msg) msg = FIPAMessage(message_id=new_msg_id, dialogue_id=propose.get("dialogue_id"), target=propose.get("id"), performative=FIPAMessage.Performative.ACCEPT) dialogue.outgoing_extend(msg) msg_bytes = FIPASerializer().encode(msg) result = Envelope(to=dialogue.dialogue_label.dialogue_opponent_pbk, sender=self.context.agent_public_key, protocol_id=FIPAMessage.protocol_id, message=msg_bytes) else: logger.debug("[{}]: Declining propose (as {})".format(self.context.agent_name, dialogue.role)) msg = FIPAMessage(message_id=new_msg_id, dialogue_id=propose.get("dialogue_id"), target=propose.get("id"), performative=FIPAMessage.Performative.DECLINE) dialogue.outgoing_extend(msg) msg_bytes = FIPASerializer().encode(msg) result = Envelope(to=dialogue.dialogue_label.dialogue_opponent_pbk, sender=self.context.agent_public_key, protocol_id=FIPAMessage.protocol_id, message=msg_bytes) dialogues = cast(Dialogues, self.context.dialogues) dialogues.dialogue_stats.add_dialogue_endstate(Dialogue.EndState.DECLINED_PROPOSE, dialogue.is_self_initiated) self.context.outbox.put(result)
def test_decision_maker_hand_tx_ready_for_signing(self): """Test that the decision maker can handle a message that is ready for signing.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SIGNING, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 0}, ledger_id=self.ledger_id, info=self.info, signing_payload={"key": b"some_bytes"}, ) self.decision_maker.handle(tx_message) assert not self.decision_maker.message_out_queue.empty() self.decision_maker.message_out_queue.get()
def test_is_affordable_off_chain(self): """Test the off_chain message.""" tx_message = TransactionMessage( performative=TransactionMessage.Performative. PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[PublicId(AUTHOR, "a_skill", "0.1.0")], tx_id=self.tx_id, tx_sender_addr=self.tx_sender_addr, tx_counterparty_addr=self.tx_counterparty_addr, tx_amount_by_currency_id={"FET": -20}, tx_sender_fee=0, tx_counterparty_fee=0, tx_quantities_by_good_id={"good_id": 10}, ledger_id="off_chain", info=self.info, tx_nonce="Transaction nonce", ) assert self.decision_maker_handler._is_affordable(tx_message)