Exemple #1
0
    def _update_ownership_and_preferences(
        self, tac_msg: TacMessage, tac_dialogue: TacDialogue
    ) -> None:
        """
        Update ownership and preferences.

        :param tac_msg: the game data
        :param tac_dialogue: the tac dialogue
        :return: None
        """
        state_update_dialogues = cast(
            StateUpdateDialogues, self.context.state_update_dialogues
        )
        state_update_msg = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.INITIALIZE,
            dialogue_reference=state_update_dialogues.new_self_initiated_dialogue_reference(),
            amount_by_currency_id=tac_msg.amount_by_currency_id,
            quantities_by_good_id=tac_msg.quantities_by_good_id,
            exchange_params_by_currency_id=tac_msg.exchange_params_by_currency_id,
            utility_params_by_good_id=tac_msg.utility_params_by_good_id,
        )
        self.context.shared_state["fee_by_currency_id"] = tac_msg.fee_by_currency_id
        state_update_msg.counterparty = "decision_maker"
        state_update_dialogue = cast(
            Optional[StateUpdateDialogue],
            state_update_dialogues.update(state_update_msg),
        )
        assert state_update_dialogue is not None, "StateUpdateDialogue not created."
        game = cast(Game, self.context.game)
        game.state_update_dialogue = state_update_dialogue
        self.context.decision_maker_message_queue.put_nowait(state_update_msg)
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'StateUpdate' message.

        :param obj: the bytes object.
        :return: the 'StateUpdate' message.
        """
        state_update_pb = state_update_pb2.StateUpdateMessage()
        state_update_pb.ParseFromString(obj)
        message_id = state_update_pb.message_id
        dialogue_reference = (
            state_update_pb.dialogue_starter_reference,
            state_update_pb.dialogue_responder_reference,
        )
        target = state_update_pb.target

        performative = state_update_pb.WhichOneof("performative")
        performative_id = StateUpdateMessage.Performative(str(performative))
        performative_content = dict()  # type: Dict[str, Any]
        if performative_id == StateUpdateMessage.Performative.INITIALIZE:
            exchange_params_by_currency_id = (
                state_update_pb.initialize.exchange_params_by_currency_id
            )
            exchange_params_by_currency_id_dict = dict(exchange_params_by_currency_id)
            performative_content[
                "exchange_params_by_currency_id"
            ] = exchange_params_by_currency_id_dict
            utility_params_by_good_id = (
                state_update_pb.initialize.utility_params_by_good_id
            )
            utility_params_by_good_id_dict = dict(utility_params_by_good_id)
            performative_content[
                "utility_params_by_good_id"
            ] = utility_params_by_good_id_dict
            amount_by_currency_id = state_update_pb.initialize.amount_by_currency_id
            amount_by_currency_id_dict = dict(amount_by_currency_id)
            performative_content["amount_by_currency_id"] = amount_by_currency_id_dict
            quantities_by_good_id = state_update_pb.initialize.quantities_by_good_id
            quantities_by_good_id_dict = dict(quantities_by_good_id)
            performative_content["quantities_by_good_id"] = quantities_by_good_id_dict
        elif performative_id == StateUpdateMessage.Performative.APPLY:
            amount_by_currency_id = state_update_pb.apply.amount_by_currency_id
            amount_by_currency_id_dict = dict(amount_by_currency_id)
            performative_content["amount_by_currency_id"] = amount_by_currency_id_dict
            quantities_by_good_id = state_update_pb.apply.quantities_by_good_id
            quantities_by_good_id_dict = dict(quantities_by_good_id)
            performative_content["quantities_by_good_id"] = quantities_by_good_id_dict
        else:
            raise ValueError("Performative not valid: {}.".format(performative_id))

        return StateUpdateMessage(
            message_id=message_id,
            dialogue_reference=dialogue_reference,
            target=target,
            performative=performative,
            **performative_content
        )
 def test_serialization_apply(self):
     """Test serialization of apply message."""
     currency_change = {"FET": 10}
     good_change = {"a_good": 1}
     msg = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.APPLY,
         amount_by_currency_id=currency_change,
         quantities_by_good_id=good_change,
     )
     assert msg._is_consistent()
     assert len(msg.valid_performatives) == 2
     encoded_msg = msg.serializer.encode(msg)
     decoded_msg = msg.serializer.decode(encoded_msg)
     assert msg == decoded_msg
 def test_message_inconsistency(self):
     """Test for an error in consistency of a message."""
     currency_endowment = {"FET": 100}
     good_endowment = {"a_good": 2}
     exchange_params = {"UNKNOWN": 10.0}
     utility_params = {"a_good": 20.0}
     tx_fee = 10
     stum = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.INITIALIZE,
         amount_by_currency_id=currency_endowment,
         quantities_by_good_id=good_endowment,
         exchange_params_by_currency_id=exchange_params,
         utility_params_by_good_id=utility_params,
         tx_fee=tx_fee,
     )
     assert not stum._is_consistent()
def test_serialization_negative():
    """Test serialization when performative is not recognized."""
    currency_change = {"FET": 10}
    good_change = {"a_good": 1}
    msg = StateUpdateMessage(
        performative=StateUpdateMessage.Performative.APPLY,
        amount_by_currency_id=currency_change,
        quantities_by_good_id=good_change,
    )

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

    encoded_tx_bytes = msg.serializer.encode(msg)
    with patch.object(StateUpdateMessage.Performative,
                      "__eq__",
                      return_value=False):
        with pytest.raises(
                ValueError,
                match=f"Performative not valid: {msg.performative}"):
            msg.serializer.decode(encoded_tx_bytes)
Exemple #6
0
    def _on_transaction_confirmed(
        self, tac_msg: TacMessage, tac_dialogue: TacDialogue
    ) -> None:
        """
        Handle 'on transaction confirmed' event emitted by the controller.

        :param tac_msg: the TacMessage.
        :param tac_dialogue: the tac dialogue
        :return: None
        """
        game = cast(Game, self.context.game)
        if game.phase.value != Phase.GAME.value:
            self.context.logger.warning(
                "we do not expect a tranasaction in game phase={}".format(
                    game.phase.value
                )
            )
            return

        self.context.logger.info(
            "received transaction confirmation from the controller: transaction_id={}".format(
                tac_msg.transaction_id
            )
        )
        state_update_dialogue = game.state_update_dialogue
        last_msg = state_update_dialogue.last_message
        assert last_msg is not None, "Could not retrieve last message."
        state_update_msg = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.APPLY,
            dialogue_reference=state_update_dialogue.dialogue_label.dialogue_reference,
            message_id=last_msg.message_id + 1,
            target=last_msg.message_id,
            amount_by_currency_id=tac_msg.amount_by_currency_id,
            quantities_by_good_id=tac_msg.quantities_by_good_id,
        )
        state_update_msg.counterparty = "decision_maker"
        state_update_dialogue.update(state_update_msg)
        self.context.decision_maker_message_queue.put_nowait(state_update_msg)
        if "confirmed_tx_ids" not in self.context.shared_state.keys():
            self.context.shared_state["confirmed_tx_ids"] = []
        self.context.shared_state["confirmed_tx_ids"].append(tac_msg.transaction_id)
 def test_message_consistency(self):
     """Test for an error in consistency of a message."""
     currency_endowment = {"FET": 100}
     good_endowment = {"a_good": 2}
     exchange_params = {"FET": 10.0}
     utility_params = {"a_good": 20.0}
     assert StateUpdateMessage(
         performative=StateUpdateMessage.Performative.INITIALIZE,
         amount_by_currency_id=currency_endowment,
         quantities_by_good_id=good_endowment,
         exchange_params_by_currency_id=exchange_params,
         utility_params_by_good_id=utility_params,
     )
     currency_change = {"FET": 10}
     good_change = {"a_good": 1}
     stum = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.APPLY,
         amount_by_currency_id=currency_change,
         quantities_by_good_id=good_change,
     )
     assert stum._is_consistent()
     assert len(stum.valid_performatives) == 2
 def test_serialization_initialize(self):
     """Test serialization of initialize message."""
     currency_endowment = {"FET": 100}
     good_endowment = {"a_good": 2}
     exchange_params = {"FET": 10.0}
     utility_params = {"a_good": 20.0}
     msg = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.INITIALIZE,
         amount_by_currency_id=currency_endowment,
         quantities_by_good_id=good_endowment,
         exchange_params_by_currency_id=exchange_params,
         utility_params_by_good_id=utility_params,
     )
     encoded_msg = msg.serializer.encode(msg)
     decoded_msg = msg.serializer.decode(encoded_msg)
     assert msg == decoded_msg
Exemple #9
0
    def _update_ownership_and_preferences(self, tac_msg: TacMessage,
                                          tac_dialogue: TacDialogue) -> None:
        """
        Update ownership and preferences.

        :param tac_msg: the game data
        :param tac_dialogue: the tac dialogue
        :return: None
        """
        state_update_msg = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.INITIALIZE,
            amount_by_currency_id=tac_msg.amount_by_currency_id,
            quantities_by_good_id=tac_msg.quantities_by_good_id,
            exchange_params_by_currency_id=tac_msg.
            exchange_params_by_currency_id,
            utility_params_by_good_id=tac_msg.utility_params_by_good_id,
            tx_fee=tac_msg.tx_fee,
        )
        self.context.decision_maker_message_queue.put_nowait(state_update_msg)
Exemple #10
0
    def _on_transaction_confirmed(self, tac_msg: TacMessage,
                                  tac_dialogue: TacDialogue) -> None:
        """
        Handle 'on transaction confirmed' event emitted by the controller.

        :param tac_msg: the TacMessage.
        :param tac_dialogue: the tac dialogue
        :return: None
        """
        self.context.logger.info(
            "[{}]: Received transaction confirmation from the controller: transaction_id={}"
            .format(self.context.agent_name, tac_msg.tx_id[-10:]))
        state_update_msg = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.APPLY,
            amount_by_currency_id=tac_msg.amount_by_currency_id,
            quantities_by_good_id=tac_msg.quantities_by_good_id,
        )
        self.context.decision_maker_message_queue.put_nowait(state_update_msg)
        if "confirmed_tx_ids" not in self.context.shared_state.keys():
            self.context.shared_state["confirmed_tx_ids"] = []
        self.context.shared_state["confirmed_tx_ids"].append(tac_msg.tx_id)
def test_light_protocol_rule_3_target_less_than_message_id():
    """Test that if message_id is not 1, target must be > message_id"""
    with patch.object(aea.protocols.state_update.message.logger,
                      "error") as mock_logger:
        currency_endowment = {"FET": 100}
        good_endowment = {"a_good": 2}
        exchange_params = {"FET": 10.0}
        utility_params = {"a_good": 20.0}
        message_id = 2
        target = 2
        assert StateUpdateMessage(
            message_id=message_id,
            target=target,
            performative=StateUpdateMessage.Performative.INITIALIZE,
            amount_by_currency_id=currency_endowment,
            quantities_by_good_id=good_endowment,
            exchange_params_by_currency_id=exchange_params,
            utility_params_by_good_id=utility_params,
        )

        mock_logger.assert_any_call(
            f"Invalid 'target'. Expected an integer between 1 and {message_id - 1} inclusive. Found {target}."
        )
    def test_decision_maker_handle_state_update_initialize_and_apply(self):
        """Test the handle method for a stateUpdate message with Initialize and Apply performative."""
        good_holdings = {"good_id": 2}
        currency_holdings = {"FET": 100}
        utility_params = {"good_id": 20.0}
        exchange_params = {"FET": 10.0}
        currency_deltas = {"FET": -10}
        good_deltas = {"good_id": 1}

        state_update_dialogues = StateUpdateDialogues("agent")
        state_update_message_1 = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.INITIALIZE,
            dialogue_reference=state_update_dialogues.new_self_initiated_dialogue_reference(),
            amount_by_currency_id=currency_holdings,
            quantities_by_good_id=good_holdings,
            exchange_params_by_currency_id=exchange_params,
            utility_params_by_good_id=utility_params,
        )
        state_update_message_1.counterparty = "decision_maker"
        state_update_dialogue = cast(
            Optional[StateUpdateDialogue],
            state_update_dialogues.update(state_update_message_1),
        )
        assert state_update_dialogue is not None, "StateUpdateDialogue not created"
        self.decision_maker.handle(state_update_message_1)
        assert (
            self.decision_maker_handler.context.ownership_state.amount_by_currency_id
            is not None
        )
        assert (
            self.decision_maker_handler.context.ownership_state.quantities_by_good_id
            is not None
        )
        assert (
            self.decision_maker_handler.context.preferences.exchange_params_by_currency_id
            is not None
        )
        assert (
            self.decision_maker_handler.context.preferences.utility_params_by_good_id
            is not None
        )

        state_update_message_2 = StateUpdateMessage(
            performative=StateUpdateMessage.Performative.APPLY,
            dialogue_reference=state_update_dialogue.dialogue_label.dialogue_reference,
            message_id=state_update_message_1.message_id + 1,
            target=state_update_message_1.message_id,
            amount_by_currency_id=currency_deltas,
            quantities_by_good_id=good_deltas,
        )
        state_update_message_2.counterparty = "decision_maker"
        assert state_update_dialogue.update(state_update_message_2)
        self.decision_maker.handle(state_update_message_2)
        expected_amount_by_currency_id = {
            key: currency_holdings.get(key, 0) + currency_deltas.get(key, 0)
            for key in set(currency_holdings) | set(currency_deltas)
        }
        expected_quantities_by_good_id = {
            key: good_holdings.get(key, 0) + good_deltas.get(key, 0)
            for key in set(good_holdings) | set(good_deltas)
        }
        assert (
            self.decision_maker_handler.context.ownership_state.amount_by_currency_id
            == expected_amount_by_currency_id
        ), "The amount_by_currency_id must be equal with the expected amount."
        assert (
            self.decision_maker_handler.context.ownership_state.quantities_by_good_id
            == expected_quantities_by_good_id
        )