Beispiel #1
0
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'StateUpdate' message.

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

        state_update_pb.ParseFromString(message_pb.dialogue_message.content)
        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)
Beispiel #2
0
 def test_serialization_end(self):
     """Test serialization of end message."""
     msg = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.END, )
     assert msg._is_consistent()
     assert len(msg.valid_performatives) == 3
     encoded_msg = msg.serializer.encode(msg)
     decoded_msg = msg.serializer.decode(encoded_msg)
     assert msg == decoded_msg
Beispiel #3
0
 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) == 3
     encoded_msg = msg.serializer.encode(msg)
     decoded_msg = msg.serializer.decode(encoded_msg)
     assert msg == decoded_msg
Beispiel #4
0
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)
Beispiel #5
0
 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) == 3
     stum = StateUpdateMessage(
         performative=StateUpdateMessage.Performative.END, )
     assert stum._is_consistent()
Beispiel #6
0
    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_dialogue = cast(
            Optional[StateUpdateDialogue],
            state_update_dialogues.create_with_message("decision_maker",
                                                       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 = state_update_dialogue.reply(
            performative=StateUpdateMessage.Performative.APPLY,
            amount_by_currency_id=currency_deltas,
            quantities_by_good_id=good_deltas,
        )
        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)
Beispiel #7
0
 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}
     with pytest.raises(ValueError, match="Field .* is not supported"):
         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,
             non_exists_field="some value",
         )
Beispiel #8
0
 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
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(_default_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}."
        )