コード例 #1
0
ファイル: base.py プロジェクト: pbukva/agents-aea
    def _handle_tx_message_for_signing(self, tx_message: TransactionMessage) -> None:
        """
        Handle a transaction message for signing.

        :param tx_message: the transaction message
        :return: None
        """
        if self._is_acceptable_for_signing(tx_message):
            if self._is_valid_message(tx_message):
                tx_signature = self._sign_tx_hash(tx_message)
                tx_message_response = TransactionMessage.respond_signing(
                    tx_message,
                    performative=TransactionMessage.Performative.SUCCESSFUL_SIGNING,
                    signed_payload={"tx_signature": tx_signature},
                )
            if self._is_valid_tx(tx_message):
                tx_signed = self._sign_ledger_tx(tx_message)
                tx_message_response = TransactionMessage.respond_signing(
                    tx_message,
                    performative=TransactionMessage.Performative.SUCCESSFUL_SIGNING,
                    signed_payload={"tx_signed": tx_signed},
                )
        else:
            tx_message_response = TransactionMessage.respond_signing(
                tx_message,
                performative=TransactionMessage.Performative.REJECTED_SIGNING,
            )
        self.message_out_queue.put(tx_message_response)
コード例 #2
0
    def _handle_tx_message(self, tx_message: TransactionMessage) -> None:
        """
        Handle a transaction message.

        :param tx_message: the transaction message
        :return: None
        """
        # if not self.goal_pursuit_readiness.is_ready:
        #     logger.warning("[{}]: Preferences and ownership state not initialized. Refusing to process transaction!".format(self._agent_name))
        #     return
        # TODO: reintroduce above check

        # check if the transaction is acceptable and process it accordingly
        if self._is_acceptable_tx(tx_message):
            tx_digest = self._settle_tx(tx_message)
            if tx_digest is not None:
                tx_message_response = TransactionMessage.respond_with(
                    tx_message,
                    performative=TransactionMessage.Performative.ACCEPT,
                    transaction_digest=tx_digest)
            else:
                tx_message_response = TransactionMessage.respond_with(
                    tx_message,
                    performative=TransactionMessage.Performative.REJECT)
        else:
            tx_message_response = TransactionMessage.respond_with(
                tx_message,
                performative=TransactionMessage.Performative.REJECT)
        self.message_out_queue.put(tx_message_response)
コード例 #3
0
    def _is_acceptable_tx(self, tx_message: TransactionMessage) -> bool:
        """
        Check if the tx is acceptable.

        :param tx_message: the transaction message
        :return: whether the transaction is acceptable or not
        """
        if tx_message.get("ledger_id") is not None:
            amount = cast(int, tx_message.get("amount"))
            counterparty_tx_fee = cast(int,
                                       tx_message.get("counterparty_tx_fee"))
            sender_tx_fee = cast(int, tx_message.get("sender_tx_fee"))
            # adjust payment amount to reflect transaction fee split
            amount -= counterparty_tx_fee
            tx_fee = counterparty_tx_fee + sender_tx_fee
            payable = amount + tx_fee
            is_correct_format = isinstance(payable, int)
            crypto_object = self._wallet.crypto_objects.get(
                tx_message.get("ledger_id"))
            balance = self.ledger_apis.token_balance(
                crypto_object.identifier, cast(str, crypto_object.address))
            is_affordable = payable <= balance
            # TODO check against preferences and other constraints
            is_acceptable = is_correct_format and is_affordable
        else:
            is_acceptable = self.preferences.get_score_diff_from_transaction(
                self.ownership_state, tx_message) >= 0.0
        return is_acceptable
コード例 #4
0
    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
コード例 #5
0
ファイル: base.py プロジェクト: pbukva/agents-aea
    def _handle_tx_message_for_settlement(self, tx_message) -> None:
        """
        Handle a transaction message for settlement.

        :param tx_message: the transaction message
        :return: None
        """
        if self._is_acceptable_for_settlement(tx_message):
            tx_digest = self._settle_tx(tx_message)
            if tx_digest is not None:
                tx_message_response = TransactionMessage.respond_settlement(
                    tx_message,
                    performative=TransactionMessage.Performative.SUCCESSFUL_SETTLEMENT,
                    tx_digest=tx_digest,
                )
            else:
                tx_message_response = TransactionMessage.respond_settlement(
                    tx_message,
                    performative=TransactionMessage.Performative.FAILED_SETTLEMENT,
                )
        else:
            tx_message_response = TransactionMessage.respond_settlement(
                tx_message,
                performative=TransactionMessage.Performative.REJECTED_SETTLEMENT,
            )
        self.message_out_queue.put(tx_message_response)
コード例 #6
0
    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()
コード例 #7
0
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."
コード例 #8
0
ファイル: handlers.py プロジェクト: pbukva/agents-aea
    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:]))
コード例 #9
0
    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))
コード例 #10
0
    def handle(self, message: Message, sender: str) -> None:
        """
        Implement the reaction to a message.

        :param message: the message
        :param sender: the sender
        :return: None
        """
        tx_msg_response = cast(TransactionMessage, message)
        if tx_msg_response is not None and \
                TransactionMessage.Performative(tx_msg_response.get("performative")) == TransactionMessage.Performative.ACCEPT:
            logger.info("[{}]: transaction was successful.".format(self.context.agent_name))
            json_data = {'transaction_digest': tx_msg_response.get("transaction_digest")}
            dialogue_label = DialogueLabel.from_json(cast(Dict[str, str], tx_msg_response.get("dialogue_label")))
            dialogues = cast(Dialogues, self.context.dialogues)
            dialogue = dialogues.dialogues[dialogue_label]
            fipa_msg = cast(FIPAMessage, dialogue.last_incoming_message)
            new_message_id = cast(int, fipa_msg.get("message_id")) + 1
            new_target_id = cast(int, fipa_msg.get("target")) + 1
            counterparty_pbk = dialogue.dialogue_label.dialogue_opponent_pbk
            inform_msg = FIPAMessage(message_id=new_message_id,
                                     dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                                     target=new_target_id,
                                     performative=FIPAMessage.Performative.INFORM,
                                     json_data=json_data)
            dialogue.outgoing_extend(inform_msg)
            self.context.outbox.put_message(to=counterparty_pbk,
                                            sender=self.context.agent_public_key,
                                            protocol_id=FIPAMessage.protocol_id,
                                            message=FIPASerializer().encode(inform_msg))
            logger.info("[{}]: informing counterparty={} of transaction digest.".format(self.context.agent_name, counterparty_pbk[-5:]))
            self._received_tx_message = True
        else:
            logger.info("[{}]: transaction was not successful.".format(self.context.agent_name))
コード例 #11
0
    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")
コード例 #12
0
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!"
コード例 #13
0
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
コード例 #14
0
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!"
コード例 #15
0
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."
コード例 #16
0
    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
コード例 #17
0
    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()
コード例 #18
0
ファイル: handlers.py プロジェクト: 8ball030/agents-aea
    def handle(self, message: Message, sender: str) -> None:
        """
        Dispatch message to relevant handler and respond.

        :param message: the message
        :param sender: the sender
        :return: None
        """
        tx_message = cast(TransactionMessage, message)
        if TransactionMessage.Performative(tx_message.get(
                "performative")) == TransactionMessage.Performative.ACCEPT:
            logger.info(
                "[{}]: transaction confirmed by decision maker, sending to controller."
                .format(self.context.agent_name))
            game = cast(Game, self.context.game)
            msg = TACMessage(
                type=TACMessage.Type.TRANSACTION,
                transaction_id=tx_message.get("transaction_digest"),
                counterparty=tx_message.get("counterparty"),
                amount_by_currency={
                    tx_message.get("currency"): tx_message.get("amount")
                },
                sender_tx_fee=tx_message.get("sender_tx_fee"),
                counterparty_tx_fee=tx_message.get("counterparty_tx_fee"),
                quantities_by_good_pbk=tx_message.get(
                    "quantities_by_good_pbk"))
            self.context.outbox.put_message(
                to=game.configuration.controller_pbk,
                sender=self.context.agent_public_key,
                protocol_id=TACMessage.protocol_id,
                message=TACSerializer().encode(msg))
        else:
            logger.info("[{}]: transaction was not successful.".format(
                self.context.agent_name))
コード例 #19
0
ファイル: base.py プロジェクト: pbukva/agents-aea
    def _settle_tx(self, tx_message: TransactionMessage) -> Optional[str]:
        """
        Settle the tx.

        :param tx_message: the transaction message
        :return: the transaction digest
        """
        if tx_message.ledger_id == OFF_CHAIN:
            logger.info(
                "[{}]: Cannot settle transaction, settlement happens off chain!".format(
                    self._agent_name
                )
            )
            tx_digest = OFF_CHAIN_SETTLEMENT_DIGEST
        else:
            logger.info("[{}]: Settling transaction on chain!".format(self._agent_name))
            crypto_object = self.wallet.crypto_objects.get(tx_message.ledger_id)
            tx_digest = self.ledger_apis.transfer(
                crypto_object,
                tx_message.tx_counterparty_addr,
                tx_message.counterparty_amount,
                tx_message.fees,
                info=tx_message.info,
                tx_nonce=cast(str, tx_message.get("tx_nonce")),
            )
        return tx_digest
コード例 #20
0
    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"
コード例 #21
0
ファイル: test_registries.py プロジェクト: pbukva/agents-aea
    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()
コード例 #22
0
    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)
コード例 #23
0
    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()
コード例 #24
0
    def check_transaction_is_consistent(
            self, tx_message: TransactionMessage) -> bool:
        """
        Check if the transaction is consistent.

        E.g. check that the agent state has enough money if it is a buyer
        or enough holdings if it is a seller.
        :return: True if the transaction is legal wrt the current state, false otherwise.
        """
        currency_pbk = cast(str, tx_message.get("currency_pbk"))
        if tx_message.get("is_sender_buyer"):
            # check if we have the money to cover amount and tx fee.
            result = self.amount_by_currency[currency_pbk] >= cast(
                int, tx_message.get("amount")) + cast(
                    int, tx_message.get("sender_tx_fee"))
        else:
            # check if we have the goods.
            result = True
            quantities_by_good_pbk = cast(
                Dict[str, int], tx_message.get("quantities_by_good_pbk"))
            for good_pbk, quantity in quantities_by_good_pbk.items():
                result = result and (self.quantities_by_good_pbk[good_pbk] >=
                                     quantity)
            # check if we have the money to cover tx fee.
            result = self.amount_by_currency[currency_pbk] + cast(
                int, tx_message.get("amount")) >= cast(
                    int, tx_message.get("sender_tx_fee"))
        return result
コード例 #25
0
    def _settle_tx(self, tx_message: TransactionMessage) -> Optional[str]:
        """
        Settle the tx.

        :param tx_message: the transaction message
        :return: the transaction digest
        """
        logger.info("[{}]: Settling transaction!".format(self._agent_name))
        if tx_message.get("ledger_id") is not None:
            amount = cast(int, tx_message.get("amount"))
            counterparty_tx_fee = cast(int,
                                       tx_message.get("counterparty_tx_fee"))
            sender_tx_fee = cast(int, tx_message.get("sender_tx_fee"))
            counterparty_address = cast(str, tx_message.get("counterparty"))
            # adjust payment amount to reflect transaction fee split
            amount -= counterparty_tx_fee
            tx_fee = counterparty_tx_fee + sender_tx_fee
            crypto_object = self._wallet.crypto_objects.get(
                tx_message.get("ledger_id"))
            tx_digest = self.ledger_apis.transfer(crypto_object.identifier,
                                                  crypto_object,
                                                  counterparty_address, amount,
                                                  tx_fee)
        else:
            tx_digest = cast(str, tx_message.get("transaction_id"))
        return tx_digest
コード例 #26
0
 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"},
         )
コード例 #27
0
    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
コード例 #28
0
    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
コード例 #29
0
ファイル: base.py プロジェクト: greencultureai/agents-aea
    def _handle_tx_message_for_signing(self,
                                       tx_message: TransactionMessage) -> None:
        """
        Handle a transaction message for signing.

        :param tx_message: the transaction message
        :return: None
        """
        if self._is_acceptable_for_signing(tx_message):
            tx_signature = self._sign_tx(tx_message)
            tx_message_response = TransactionMessage.respond_signing(
                tx_message,
                performative=TransactionMessage.Performative.
                SUCCESSFUL_SIGNING,
                tx_signature=tx_signature,
            )
        else:
            tx_message_response = TransactionMessage.respond_signing(
                tx_message,
                performative=TransactionMessage.Performative.REJECTED_SIGNING,
            )
        self.message_out_queue.put(tx_message_response)
コード例 #30
0
    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!"