예제 #1
0
 def test_handle_message_signing_ethereum_deprecated(self):
     """Test message signing for ethereum deprecated."""
     message = b"0x11f3f9487724404e3a1fb7252a3226"
     signing_dialogues = SigningDialogues("agent5")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id=ETHEREUM,
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_message=RawMessage(ETHEREUM, message, is_deprecated_mode=True),
     )
     signing_msg.counterparty = "decision_maker"
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     assert (
         signing_msg_response.performative
         == SigningMessage.Performative.SIGNED_MESSAGE
     )
     assert signing_msg_response.skill_callback_ids == signing_msg.skill_callback_ids
     assert type(signing_msg_response.signed_message) == SignedMessage
     assert signing_msg_response.signed_message.is_deprecated_mode
예제 #2
0
    def _handle_raw_transaction(
            self, ledger_api_msg: LedgerApiMessage,
            ledger_api_dialogue: LedgerApiDialogue) -> None:
        """
        Handle a message of raw_transaction performative.

        :param ledger_api_message: the ledger api message
        :param ledger_api_dialogue: the ledger api dialogue
        """
        self.context.logger.info(
            "received raw transaction={}".format(ledger_api_msg))
        signing_dialogues = cast(SigningDialogues,
                                 self.context.signing_dialogues)
        signing_msg = SigningMessage(
            performative=SigningMessage.Performative.SIGN_TRANSACTION,
            dialogue_reference=signing_dialogues.
            new_self_initiated_dialogue_reference(),
            skill_callback_ids=(str(self.context.skill_id), ),
            raw_transaction=ledger_api_msg.raw_transaction,
            terms=ledger_api_dialogue.associated_fipa_dialogue.terms,
            skill_callback_info={},
        )
        signing_msg.counterparty = "decision_maker"
        signing_dialogue = cast(Optional[SigningDialogue],
                                signing_dialogues.update(signing_msg))
        assert signing_dialogue is not None, "Error when creating signing dialogue"
        signing_dialogue.associated_fipa_dialogue = (
            ledger_api_dialogue.associated_fipa_dialogue)
        self.context.decision_maker_message_queue.put_nowait(signing_msg)
        self.context.logger.info(
            "proposing the transaction to the decision maker. Waiting for confirmation ..."
        )
예제 #3
0
 def test_handle_tx_signing_fetchai(self):
     """Test tx signing for fetchai."""
     tx = TokenTxFactory.transfer(
         FetchaiAddress("v3sZs7gKKz9xmoTo9yzRkfHkjYuX42MzXaq4eVjGHxrX9qu3U"),
         FetchaiAddress("2bzQNV4TTjMAiKZe85EyLUttoFpHHuksRzUUBYB1brt98pMXKK"),
         1,
         1,
         [],
     )
     signing_dialogues = SigningDialogues("agent1")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_TRANSACTION,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id=FETCHAI,
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_transaction=RawTransaction(FETCHAI, tx),
     )
     signing_msg.counterparty = "decision_maker"
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     assert (
         signing_msg_response.performative
         == SigningMessage.Performative.SIGNED_TRANSACTION
     )
     assert signing_msg_response.skill_callback_ids == signing_msg.skill_callback_ids
     assert type(signing_msg_response.signed_transaction.body) == FetchaiTransaction
예제 #4
0
 def test_handle_tx_signing_ethereum(self):
     """Test tx signing for ethereum."""
     tx = {"gasPrice": 30, "nonce": 1, "gas": 20000}
     signing_dialogues = SigningDialogues("agent2")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_TRANSACTION,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id=ETHEREUM,
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_transaction=RawTransaction(ETHEREUM, tx),
     )
     signing_msg.counterparty = "decision_maker"
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     assert (
         signing_msg_response.performative
         == SigningMessage.Performative.SIGNED_TRANSACTION
     )
     assert signing_msg_response.skill_callback_ids == signing_msg.skill_callback_ids
     assert (
         type(signing_msg_response.signed_transaction.body)
         == eth_account.datastructures.AttributeDict
     )
예제 #5
0
 def test_handle_tx_signing_unknown(self):
     """Test tx signing for unknown."""
     tx = {}
     signing_dialogues = SigningDialogues("agent")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_TRANSACTION,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id="unknown",
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_transaction=RawTransaction("unknown", tx),
     )
     signing_msg.counterparty = "decision_maker"
     signing_dialogue = signing_dialogues.update(signing_msg)
     assert signing_dialogue is not None
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     signing_msg_response.counterparty = signing_msg.counterparty
     signing_msg_response.is_incoming = True
     recovered_dialogue = signing_dialogues.update(signing_msg_response)
     assert recovered_dialogue is not None and recovered_dialogue == signing_dialogue
     assert signing_msg_response.performative == SigningMessage.Performative.ERROR
     assert signing_msg_response.skill_callback_ids == signing_msg.skill_callback_ids
     assert (
         signing_msg_response.error_code
         == SigningMessage.ErrorCode.UNSUCCESSFUL_TRANSACTION_SIGNING
     )
예제 #6
0
 def test_handle_message_signing_unknown_and_two_dialogues(self):
     """Test message signing for unknown."""
     message = b"0x11f3f9487724404e3a1fb7252a322656b90ba0455a2ca5fcdcbe6eeee5f8126d"
     signing_dialogues = SigningDialogues("agent")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id="unknown",
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_message=RawMessage("unknown", message),
     )
     signing_msg.counterparty = "decision_maker"
     signing_dialogue = signing_dialogues.update(signing_msg)
     assert signing_dialogue is not None
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     signing_msg_response.counterparty = signing_msg.counterparty
     signing_msg_response.is_incoming = True
     recovered_dialogue = signing_dialogues.update(signing_msg_response)
     assert recovered_dialogue is not None and recovered_dialogue == signing_dialogue
     assert signing_msg_response.performative == SigningMessage.Performative.ERROR
     assert signing_msg_response.skill_callback_ids == signing_msg.skill_callback_ids
     assert (
         signing_msg_response.error_code
         == SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING
     )
예제 #7
0
 def test_sign_message(self):
     """Test for an error for a sign transaction message."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         terms=self.terms,
         raw_message=RawMessage(self.ledger_id, "message"),
     )
     assert tx_msg._is_consistent()
     encoded_tx_msg = tx_msg.encode()
     decoded_tx_msg = tx_msg.serializer.decode(encoded_tx_msg)
     assert tx_msg == decoded_tx_msg
예제 #8
0
 def test_signed_message(self):
     """Test for an error for a signed message."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGNED_MESSAGE,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         signed_message=SignedMessage(self.ledger_id, "message"),
     )
     assert tx_msg._is_consistent()
     encoded_tx_msg = tx_msg.encode()
     decoded_tx_msg = tx_msg.serializer.decode(encoded_tx_msg)
     assert tx_msg == decoded_tx_msg
예제 #9
0
 def test_signed_transaction(self):
     """Test for an error for a signed transaction."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGNED_TRANSACTION,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         signed_transaction=SignedTransaction(self.ledger_id, "signature"),
     )
     assert tx_msg._is_consistent()
     encoded_tx_msg = tx_msg.encode()
     decoded_tx_msg = tx_msg.serializer.decode(encoded_tx_msg)
     assert tx_msg == decoded_tx_msg
예제 #10
0
def test_serialization_negative():
    """Test serialization when performative is not recognized."""
    skill_callback_ids = (str(PublicId("author", "a_skill", "0.1.0")), )
    skill_callback_info = {"some_string": "some_string"}
    tx_msg = SigningMessage(
        performative=SigningMessage.Performative.ERROR,
        message_id=2,
        target=1,
        skill_callback_ids=skill_callback_ids,
        skill_callback_info=skill_callback_info,
        error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING,
    )

    with patch.object(SigningMessage.Performative,
                      "__eq__",
                      return_value=False):
        with pytest.raises(
                ValueError,
                match=f"Performative not valid: {tx_msg.performative}"):
            tx_msg.serializer.encode(tx_msg)

    encoded_tx_bytes = tx_msg.serializer.encode(tx_msg)
    with patch.object(SigningMessage.Performative,
                      "__eq__",
                      return_value=False):
        with pytest.raises(
                ValueError,
                match=f"Performative not valid: {tx_msg.performative}"):
            tx_msg.serializer.decode(encoded_tx_bytes)
예제 #11
0
 def test_error_message(self):
     """Test for an error for an error message."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.ERROR,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING,
     )
     assert tx_msg._is_consistent()
     encoded_tx_msg = tx_msg.encode()
     decoded_tx_msg = tx_msg.serializer.decode(encoded_tx_msg)
     assert tx_msg == decoded_tx_msg
     assert str(tx_msg.performative) == "error"
     assert len(tx_msg.valid_performatives) == 5
예제 #12
0
 def _handle_signing_message(self, signing_message: SigningMessage):
     """Handle transaction message from the Decision Maker."""
     skill_callback_ids = [
         PublicId.from_str(skill_id)
         for skill_id in signing_message.skill_callback_ids
     ]
     for skill_id in skill_callback_ids:
         handler = self.resources.handler_registry.fetch_by_protocol_and_skill(
             signing_message.protocol_id, skill_id)
         if handler is not None:
             logger.debug("Calling handler {} of skill {}".format(
                 type(handler), skill_id))
             signing_message.counterparty = "decision_maker"  # TODO: temp fix
             signing_message.is_incoming = True
             handler.handle(cast(Message, signing_message))
         else:
             logger.warning(
                 "No internal handler fetched for skill_id={}".format(
                     skill_id))
예제 #13
0
    def _handle_message_signing(self, signing_msg: SigningMessage,
                                signing_dialogue: SigningDialogue) -> None:
        """
        Handle a message for signing.

        :param signing_msg: the signing message
        :param signing_dialogue: the signing dialogue
        :return: None
        """
        signing_msg_response = SigningMessage(
            performative=SigningMessage.Performative.ERROR,
            dialogue_reference=signing_dialogue.dialogue_label.
            dialogue_reference,
            target=signing_msg.message_id,
            message_id=signing_msg.message_id + 1,
            skill_callback_ids=signing_msg.skill_callback_ids,
            skill_callback_info=signing_msg.skill_callback_info,
            error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING,
        )
        if self._is_acceptable_for_signing(signing_msg):
            signed_message = self.wallet.sign_message(
                signing_msg.raw_message.ledger_id,
                signing_msg.raw_message.body,
                signing_msg.raw_message.is_deprecated_mode,
            )
            if signed_message is not None:
                signing_msg_response = SigningMessage(
                    performative=SigningMessage.Performative.SIGNED_MESSAGE,
                    dialogue_reference=signing_dialogue.dialogue_label.
                    dialogue_reference,
                    target=signing_msg.message_id,
                    message_id=signing_msg.message_id + 1,
                    skill_callback_ids=signing_msg.skill_callback_ids,
                    skill_callback_info=signing_msg.skill_callback_info,
                    signed_message=SignedMessage(
                        signing_msg.raw_message.ledger_id,
                        signed_message,
                        signing_msg.raw_message.is_deprecated_mode,
                    ),
                )
        signing_msg_response.counterparty = signing_msg.counterparty
        signing_dialogue.update(signing_msg_response)
        self.message_out_queue.put(signing_msg_response)
예제 #14
0
    def test_handle_internal_messages(self):
        """Test that the internal messages are handled."""
        t = SigningMessage(
            performative=SigningMessage.Performative.SIGNED_TRANSACTION,
            skill_callback_ids=(str(PublicId("dummy_author", "dummy",
                                             "0.1.0")), ),
            skill_callback_info={},
            # crypto_id="ledger_id",
            signed_transaction=SignedTransaction("ledger_id", "tx"),
        )
        t.counterparty = "skill"
        t.sender = "decision_maker"
        self.aea.decision_maker.message_out_queue.put(t)
        self.aea._filter.handle_internal_messages()

        internal_handlers_list = self.aea.resources.get_handlers(t.protocol_id)
        assert len(internal_handlers_list) == 1
        internal_handler = internal_handlers_list[0]
        assert len(internal_handler.handled_internal_messages) == 1
        self.aea.teardown()
예제 #15
0
    def _handle_transaction_signing(self, signing_msg: SigningMessage,
                                    signing_dialogue: SigningDialogue) -> None:
        """
        Handle a transaction for signing.

        :param signing_msg: the signing message
        :param signing_dialogue: the signing dialogue
        :return: None
        """
        signing_msg_response = SigningMessage(
            performative=SigningMessage.Performative.ERROR,
            dialogue_reference=signing_dialogue.dialogue_label.
            dialogue_reference,
            target=signing_msg.message_id,
            message_id=signing_msg.message_id + 1,
            skill_callback_ids=signing_msg.skill_callback_ids,
            skill_callback_info=signing_msg.skill_callback_info,
            error_code=SigningMessage.ErrorCode.
            UNSUCCESSFUL_TRANSACTION_SIGNING,
        )
        if self._is_acceptable_for_signing(signing_msg):
            signed_tx = self.wallet.sign_transaction(
                signing_msg.raw_transaction.ledger_id,
                signing_msg.raw_transaction.body)
            if signed_tx is not None:
                signing_msg_response = SigningMessage(
                    performative=SigningMessage.Performative.
                    SIGNED_TRANSACTION,
                    dialogue_reference=signing_dialogue.dialogue_label.
                    dialogue_reference,
                    target=signing_msg.message_id,
                    message_id=signing_msg.message_id + 1,
                    skill_callback_ids=signing_msg.skill_callback_ids,
                    skill_callback_info=signing_msg.skill_callback_info,
                    signed_transaction=SignedTransaction(
                        signing_msg.raw_transaction.ledger_id, signed_tx),
                )
        signing_msg_response.counterparty = signing_msg.counterparty
        signing_dialogue.update(signing_msg_response)
        self.message_out_queue.put(signing_msg_response)
예제 #16
0
    def _handle_raw_message(
        self,
        contract_api_msg: ContractApiMessage,
        contract_api_dialogue: ContractApiDialogue,
    ) -> None:
        """
        Handle a message of raw_message performative.

        :param contract_api_message: the ledger api message
        :param contract_api_dialogue: the ledger api dialogue
        """
        self.context.logger.info("[{}]: received raw message={}".format(
            self.context.agent_name, contract_api_msg))
        signing_dialogues = cast(SigningDialogues,
                                 self.context.signing_dialogues)
        signing_msg = SigningMessage(
            performative=SigningMessage.Performative.SIGN_MESSAGE,
            dialogue_reference=signing_dialogues.
            new_self_initiated_dialogue_reference(),
            skill_callback_ids=(str(self.context.skill_id), ),
            raw_message=RawMessage(
                contract_api_msg.raw_message.ledger_id,
                contract_api_msg.raw_message.body,
                is_deprecated_mode=True,
            ),
            terms=contract_api_dialogue.terms,
            skill_callback_info={},
        )
        signing_msg.counterparty = "decision_maker"
        signing_dialogue = cast(Optional[SigningDialogue],
                                signing_dialogues.update(signing_msg))
        assert signing_dialogue is not None, "Error when creating signing dialogue."
        signing_dialogue.associated_contract_api_dialogue = contract_api_dialogue
        self.context.decision_maker_message_queue.put_nowait(signing_msg)
        self.context.logger.info(
            "[{}]: proposing the transaction to the decision maker. Waiting for confirmation ..."
            .format(self.context.agent_name))
예제 #17
0
 def test_message_inconsistency(self):
     """Test for an error in consistency of a message."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_TRANSACTION,
         skill_callback_ids=self.skill_callback_ids,
         terms=self.terms,
     )
     assert not tx_msg._is_consistent()
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         skill_callback_ids=self.skill_callback_ids,
         terms=self.terms,
     )
     assert not tx_msg._is_consistent()
예제 #18
0
    def generate_signing_message(
        self,
        performative: SigningMessage.Performative,
        proposal_description: Description,
        dialogue_label: DialogueLabel,
        role: FipaDialogue.Role,
        agent_addr: Address,
    ) -> SigningMessage:
        """
        Generate the transaction message from the description and the dialogue.

        :param proposal_description: the description of the proposal
        :param dialogue_label: the dialogue label
        :param role: the role of the agent (seller or buyer)
        :param agent_addr: the address of the agent
        :return: a transaction message
        """
        is_seller = role == FipaDialogue.Role.SELLER

        goods_component = copy.copy(proposal_description.values)
        [  # pylint: disable=expression-not-assigned
            goods_component.pop(key)
            for key in ["fee", "price", "currency_id", "nonce", "ledger_id"]
        ]
        # switch signs based on whether seller or buyer role
        amount = (proposal_description.values["price"]
                  if is_seller else -proposal_description.values["price"])
        fee = proposal_description.values["fee"]
        if is_seller:
            for good_id in goods_component.keys():
                goods_component[good_id] = goods_component[good_id] * (-1)
        amount_by_currency_id = {
            proposal_description.values["currency_id"]: amount
        }
        fee_by_currency_id = {proposal_description.values["currency_id"]: fee}
        nonce = proposal_description.values["nonce"]
        ledger_id = proposal_description.values["ledger_id"]
        terms = Terms(
            ledger_id=ledger_id,
            sender_address=agent_addr,
            counterparty_address=dialogue_label.dialogue_opponent_addr,
            amount_by_currency_id=amount_by_currency_id,
            is_sender_payable_tx_fee=not is_seller,
            quantities_by_good_id=goods_component,
            nonce=nonce,
            fee_by_currency_id=fee_by_currency_id,
        )
        skill_callback_ids = (str(self.context.skill_id), )
        signing_dialogues = cast(SigningDialogues,
                                 self.context.signing_dialogues)
        skill_callback_info = {"dialogue_label": str(dialogue_label)}
        raw_message = RawMessage(ledger_id=ledger_id,
                                 body=terms.sender_hash.encode("utf-8"))
        signing_msg = SigningMessage(
            performative=performative,
            dialogue_reference=signing_dialogues.
            new_self_initiated_dialogue_reference(),
            skill_callback_ids=skill_callback_ids,
            terms=terms,
            skill_callback_info=skill_callback_info,
            raw_message=raw_message,
        )
        signing_msg.counterparty = "decision_maker"
        return signing_msg
예제 #19
0
def test_consistency_check_negative():
    """Test the consistency check, negative case."""
    tx_msg = SigningMessage(
        performative=SigningMessage.Performative.SIGN_TRANSACTION, )
    assert not tx_msg._is_consistent()
예제 #20
0
 def test_message_consistency(self):
     """Test for an error in consistency of a message."""
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_TRANSACTION,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         terms=self.terms,
         raw_transaction=RawTransaction(self.ledger_id, "transaction"),
     )
     assert tx_msg._is_consistent()
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         terms=self.terms,
         raw_message=RawMessage(self.ledger_id, "message"),
     )
     assert tx_msg._is_consistent()
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGNED_TRANSACTION,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         signed_transaction=SignedTransaction(self.ledger_id, "signature"),
     )
     assert tx_msg._is_consistent()
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGNED_MESSAGE,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         signed_message=SignedMessage(self.ledger_id, "message"),
     )
     assert tx_msg._is_consistent()
     tx_msg = SigningMessage(
         performative=SigningMessage.Performative.ERROR,
         message_id=2,
         target=1,
         skill_callback_ids=self.skill_callback_ids,
         skill_callback_info=self.skill_callback_info,
         error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING,
     )
     assert tx_msg._is_consistent()
     assert str(tx_msg.performative) == "error"
     assert len(tx_msg.valid_performatives) == 5
예제 #21
0
    def generate_transaction_message(  # pylint: disable=no-self-use
        self,
        performative: SigningMessage.Performative,
        proposal_description: Description,
        dialogue_label: DialogueLabel,
        role: Dialogue.Role,
        agent_addr: Address,
    ) -> SigningMessage:
        """
        Generate the transaction message from the description and the dialogue.

        :param proposal_description: the description of the proposal
        :param dialogue_label: the dialogue label
        :param role: the role of the agent (seller or buyer)
        :param agent_addr: the address of the agent
        :return: a transaction message
        """
        is_seller = role == Dialogue.Role.SELLER

        # sender_tx_fee = (
        #     proposal_description.values["seller_tx_fee"]
        #     if is_seller
        #     else proposal_description.values["buyer_tx_fee"]
        # )
        # counterparty_tx_fee = (
        #     proposal_description.values["buyer_tx_fee"]
        #     if is_seller
        #     else proposal_description.values["seller_tx_fee"]
        # )
        goods_component = copy.copy(proposal_description.values)
        [  # pylint: disable=expression-not-assigned
            goods_component.pop(key)
            for key in [
                "seller_tx_fee",
                "buyer_tx_fee",
                "price",
                "currency_id",
                "tx_nonce",
            ]
        ]
        # switch signs based on whether seller or buyer role
        amount = (
            proposal_description.values["price"]
            if is_seller
            else -proposal_description.values["price"]
        )
        if is_seller:
            for good_id in goods_component.keys():
                goods_component[good_id] = goods_component[good_id] * (-1)
        tx_amount_by_currency_id = {proposal_description.values["currency_id"]: amount}
        tx_fee_by_currency_id = {proposal_description.values["currency_id"]: 1}
        tx_nonce = proposal_description.values["tx_nonce"]
        # need to hash positive.negative side separately
        tx_hash = tx_hash_from_values(
            tx_sender_addr=agent_addr,
            tx_counterparty_addr=dialogue_label.dialogue_opponent_addr,
            tx_quantities_by_good_id=goods_component,
            tx_amount_by_currency_id=tx_amount_by_currency_id,
            tx_nonce=tx_nonce,
        )
        skill_callback_ids = (
            (PublicId.from_str("fetchai/tac_participation:0.4.0"),)
            if performative == SigningMessage.Performative.SIGN_MESSAGE
            else (PublicId.from_str("fetchai/tac_negotiation:0.5.0"),)
        )
        transaction_msg = SigningMessage(
            performative=performative,
            skill_callback_ids=skill_callback_ids,
            # tx_id=self.get_internal_tx_id(),
            terms=Terms(
                ledger_id="ethereum",
                sender_address=agent_addr,
                counterparty_address=dialogue_label.dialogue_opponent_addr,
                amount_by_currency_id=tx_amount_by_currency_id,
                is_sender_payable_tx_fee=True,  # TODO: check!
                quantities_by_good_id=goods_component,
                nonce=tx_nonce,
                fee_by_currency_id=tx_fee_by_currency_id,
            ),
            skill_callback_info={"dialogue_label": dialogue_label.json},
            message=tx_hash,
        )
        return transaction_msg
예제 #22
0
 def test_handle_messages_from_two_dialogues_same_agent(self):
     """Test message signing for unknown."""
     message = b"0x11f3f9487724404e3a1fb7252a322656b90ba0455a2ca5fcdcbe6eeee5f8126d"
     signing_dialogues = SigningDialogues("agent")
     dialogue_reference = signing_dialogues.new_self_initiated_dialogue_reference()
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         dialogue_reference=dialogue_reference,
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id="unknown",
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_message=RawMessage("unknown", message),
     )
     signing_msg.counterparty = "decision_maker"
     signing_dialogue = signing_dialogues.update(signing_msg)
     assert signing_dialogue is not None
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     assert signing_msg_response is not None
     signing_dialogues = SigningDialogues("agent")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         dialogue_reference=dialogue_reference,
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id="unknown",
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_message=RawMessage("unknown", message),
     )
     signing_msg.counterparty = "decision_maker"
     signing_dialogue = signing_dialogues.update(signing_msg)
     assert signing_dialogue is not None
     with pytest.raises(Exception):
         # Exception occurs because the same counterparty sends two identical dialogue references
         self.decision_maker.message_out_queue.get(timeout=1)
     # test twice; should work again even from same agent
     signing_dialogues = SigningDialogues("agent")
     signing_msg = SigningMessage(
         performative=SigningMessage.Performative.SIGN_MESSAGE,
         dialogue_reference=signing_dialogues.new_self_initiated_dialogue_reference(),
         skill_callback_ids=(str(PublicId("author", "a_skill", "0.1.0")),),
         skill_callback_info={},
         terms=Terms(
             ledger_id="unknown",
             sender_address="pk1",
             counterparty_address="pk2",
             amount_by_currency_id={"FET": -1},
             is_sender_payable_tx_fee=True,
             quantities_by_good_id={"good_id": 10},
             nonce="transaction nonce",
         ),
         raw_message=RawMessage("unknown", message),
     )
     signing_msg.counterparty = "decision_maker"
     signing_dialogue = signing_dialogues.update(signing_msg)
     assert signing_dialogue is not None
     self.decision_maker.message_in_queue.put_nowait(signing_msg)
     signing_msg_response = self.decision_maker.message_out_queue.get(timeout=2)
     assert signing_msg_response is not None
def run():
    # Create a private key
    create_private_key(CosmosCrypto.identifier,
                       private_key_file=COSMOS_PRIVATE_KEY_FILE_1)

    # Instantiate the builder and build the AEA
    # By default, the default protocol, error skill and stub connection are added
    builder = AEABuilder()

    builder.set_name("my_aea")

    builder.add_private_key(CosmosCrypto.identifier, COSMOS_PRIVATE_KEY_FILE_1)

    # Create our AEA
    my_aea = builder.build()

    # add a simple skill with handler
    skill_context = SkillContext(my_aea.context)
    skill_config = SkillConfig(name="simple_skill",
                               author="fetchai",
                               version="0.1.0")
    signing_handler = SigningHandler(skill_context=skill_context,
                                     name="signing_handler")
    signing_dialogues_model = SigningDialogues(skill_context=skill_context,
                                               name="signing_dialogues")

    simple_skill = Skill(
        skill_config,
        skill_context,
        handlers={signing_handler.name: signing_handler},
        models={signing_dialogues_model.name: signing_dialogues_model},
    )
    my_aea.resources.add_skill(simple_skill)

    # create a second identity
    create_private_key(CosmosCrypto.identifier,
                       private_key_file=COSMOS_PRIVATE_KEY_FILE_2)

    counterparty_wallet = Wallet(
        {CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE_2})

    counterparty_identity = Identity(
        name="counterparty_aea",
        addresses=counterparty_wallet.addresses,
        default_address_key=CosmosCrypto.identifier,
    )

    # create signing message for decision maker to sign
    terms = Terms(
        ledger_id=CosmosCrypto.identifier,
        sender_address=my_aea.identity.address,
        counterparty_address=counterparty_identity.address,
        amount_by_currency_id={"FET": -1},
        quantities_by_good_id={"some_service": 1},
        nonce="some_nonce",
        fee_by_currency_id={"FET": 0},
    )
    signing_dialogues = cast(SigningDialogues, skill_context.signing_dialogues)
    stub_transaction = LedgerApis.get_transfer_transaction(
        terms.ledger_id,
        terms.sender_address,
        terms.counterparty_address,
        terms.sender_payable_amount,
        terms.sender_fee,
        terms.nonce,
    )
    signing_msg = SigningMessage(
        performative=SigningMessage.Performative.SIGN_TRANSACTION,
        dialogue_reference=signing_dialogues.
        new_self_initiated_dialogue_reference(),
        skill_callback_ids=(str(skill_context.skill_id), ),
        raw_transaction=RawTransaction(CosmosCrypto.identifier,
                                       stub_transaction),
        terms=terms,
        skill_callback_info={"some_info_key": "some_info_value"},
    )
    signing_msg.counterparty = "decision_maker"
    signing_dialogue = cast(Optional[SigningDialogue],
                            signing_dialogues.update(signing_msg))
    assert signing_dialogue is not None
    my_aea.context.decision_maker_message_queue.put_nowait(signing_msg)

    # Set the AEA running in a different thread
    try:
        logger.info("STARTING AEA NOW!")
        t = Thread(target=my_aea.start)
        t.start()

        # Let it run long enough to interact with the decision maker
        time.sleep(1)
    finally:
        # Shut down the AEA
        logger.info("STOPPING AEA NOW!")
        my_aea.stop()
        t.join()
예제 #24
0
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'Signing' message.

        :param obj: the bytes object.
        :return: the 'Signing' message.
        """
        signing_pb = signing_pb2.SigningMessage()
        signing_pb.ParseFromString(obj)
        message_id = signing_pb.message_id
        dialogue_reference = (
            signing_pb.dialogue_starter_reference,
            signing_pb.dialogue_responder_reference,
        )
        target = signing_pb.target

        performative = signing_pb.WhichOneof("performative")
        performative_id = SigningMessage.Performative(str(performative))
        performative_content = dict()  # type: Dict[str, Any]
        if performative_id == SigningMessage.Performative.SIGN_TRANSACTION:
            skill_callback_ids = signing_pb.sign_transaction.skill_callback_ids
            skill_callback_ids_tuple = tuple(skill_callback_ids)
            performative_content[
                "skill_callback_ids"] = skill_callback_ids_tuple
            skill_callback_info = signing_pb.sign_transaction.skill_callback_info
            skill_callback_info_dict = dict(skill_callback_info)
            performative_content[
                "skill_callback_info"] = skill_callback_info_dict
            pb2_terms = signing_pb.sign_transaction.terms
            terms = Terms.decode(pb2_terms)
            performative_content["terms"] = terms
            pb2_raw_transaction = signing_pb.sign_transaction.raw_transaction
            raw_transaction = RawTransaction.decode(pb2_raw_transaction)
            performative_content["raw_transaction"] = raw_transaction
        elif performative_id == SigningMessage.Performative.SIGN_MESSAGE:
            skill_callback_ids = signing_pb.sign_message.skill_callback_ids
            skill_callback_ids_tuple = tuple(skill_callback_ids)
            performative_content[
                "skill_callback_ids"] = skill_callback_ids_tuple
            skill_callback_info = signing_pb.sign_message.skill_callback_info
            skill_callback_info_dict = dict(skill_callback_info)
            performative_content[
                "skill_callback_info"] = skill_callback_info_dict
            pb2_terms = signing_pb.sign_message.terms
            terms = Terms.decode(pb2_terms)
            performative_content["terms"] = terms
            pb2_raw_message = signing_pb.sign_message.raw_message
            raw_message = RawMessage.decode(pb2_raw_message)
            performative_content["raw_message"] = raw_message
        elif performative_id == SigningMessage.Performative.SIGNED_TRANSACTION:
            skill_callback_ids = signing_pb.signed_transaction.skill_callback_ids
            skill_callback_ids_tuple = tuple(skill_callback_ids)
            performative_content[
                "skill_callback_ids"] = skill_callback_ids_tuple
            skill_callback_info = signing_pb.signed_transaction.skill_callback_info
            skill_callback_info_dict = dict(skill_callback_info)
            performative_content[
                "skill_callback_info"] = skill_callback_info_dict
            pb2_signed_transaction = signing_pb.signed_transaction.signed_transaction
            signed_transaction = SignedTransaction.decode(
                pb2_signed_transaction)
            performative_content["signed_transaction"] = signed_transaction
        elif performative_id == SigningMessage.Performative.SIGNED_MESSAGE:
            skill_callback_ids = signing_pb.signed_message.skill_callback_ids
            skill_callback_ids_tuple = tuple(skill_callback_ids)
            performative_content[
                "skill_callback_ids"] = skill_callback_ids_tuple
            skill_callback_info = signing_pb.signed_message.skill_callback_info
            skill_callback_info_dict = dict(skill_callback_info)
            performative_content[
                "skill_callback_info"] = skill_callback_info_dict
            pb2_signed_message = signing_pb.signed_message.signed_message
            signed_message = SignedMessage.decode(pb2_signed_message)
            performative_content["signed_message"] = signed_message
        elif performative_id == SigningMessage.Performative.ERROR:
            skill_callback_ids = signing_pb.error.skill_callback_ids
            skill_callback_ids_tuple = tuple(skill_callback_ids)
            performative_content[
                "skill_callback_ids"] = skill_callback_ids_tuple
            skill_callback_info = signing_pb.error.skill_callback_info
            skill_callback_info_dict = dict(skill_callback_info)
            performative_content[
                "skill_callback_info"] = skill_callback_info_dict
            pb2_error_code = signing_pb.error.error_code
            error_code = ErrorCode.decode(pb2_error_code)
            performative_content["error_code"] = error_code
        else:
            raise ValueError(
                "Performative not valid: {}.".format(performative_id))

        return SigningMessage(message_id=message_id,
                              dialogue_reference=dialogue_reference,
                              target=target,
                              performative=performative,
                              **performative_content)