class MyScaffoldMessage(Message): """The scaffold message class.""" protocol_id = ProtocolId.from_str("fetchai/scaffold:0.1.0") serializer = MyScaffoldSerializer class Performative(Enum): """Scaffold Message types.""" def __str__(self): """Get string representation.""" return str(self.value) # pragma: no cover def __init__(self, performative: Performative, **kwargs): """ Initialize. :param performative: the type of message. """ super().__init__(performative=performative, **kwargs) assert ( self._is_consistent() ), "MyScaffoldMessage initialization inconsistent." # pragma: no cover def _is_consistent(self) -> bool: """Check that the data is consistent.""" try: raise NotImplementedError except (AssertionError, ValueError): return False # pragma: no cover return True # pragma: no cover
async def test_unsupported_protocol(ledger_apis_connection: LedgerConnection): """Test fail on protocol not supported.""" envelope = Envelope( to=str(ledger_apis_connection.connection_id), sender="test", protocol_id=ProtocolId.from_str("author/package_name:0.1.0"), message=b"message", ) with pytest.raises(ValueError): ledger_apis_connection._schedule_request(envelope)
async def _handle_envelope(self, envelope: Envelope) -> None: """Handle an envelope. :param envelope: the envelope :return: None """ if envelope.protocol_id == ProtocolId.from_str("fetchai/oef:0.1.0"): await self._handle_oef_message(envelope) else: await self._handle_agent_message(envelope)
class TProtocolNoCtMessage(Message): """A protocol for testing purposes.""" protocol_id = ProtocolId.from_str("fetchai/t_protocol_no_ct:0.1.0") class Performative(Enum): """Performatives for the t_protocol_no_ct protocol.""" PERFORMATIVE_EMPTY_CONTENTS = "performative_empty_contents" PERFORMATIVE_MT = "performative_mt" PERFORMATIVE_O = "performative_o" PERFORMATIVE_PCT = "performative_pct" PERFORMATIVE_PMT = "performative_pmt" PERFORMATIVE_PT = "performative_pt" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of TProtocolNoCtMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=TProtocolNoCtMessage.Performative(performative), **kwargs, ) self._performatives = { "performative_empty_contents", "performative_mt", "performative_o", "performative_pct", "performative_pmt", "performative_pt", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(TProtocolNoCtMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def content_bool(self) -> bool: """Get the 'content_bool' content from the message.""" assert self.is_set( "content_bool"), "'content_bool' content is not set." return cast(bool, self.get("content_bool")) @property def content_bytes(self) -> bytes: """Get the 'content_bytes' content from the message.""" assert self.is_set( "content_bytes"), "'content_bytes' content is not set." return cast(bytes, self.get("content_bytes")) @property def content_dict_bool_bool(self) -> Dict[bool, bool]: """Get the 'content_dict_bool_bool' content from the message.""" assert self.is_set("content_dict_bool_bool" ), "'content_dict_bool_bool' content is not set." return cast(Dict[bool, bool], self.get("content_dict_bool_bool")) @property def content_dict_bool_bytes(self) -> Dict[bool, bytes]: """Get the 'content_dict_bool_bytes' content from the message.""" assert self.is_set("content_dict_bool_bytes" ), "'content_dict_bool_bytes' content is not set." return cast(Dict[bool, bytes], self.get("content_dict_bool_bytes")) @property def content_dict_bool_float(self) -> Dict[bool, float]: """Get the 'content_dict_bool_float' content from the message.""" assert self.is_set("content_dict_bool_float" ), "'content_dict_bool_float' content is not set." return cast(Dict[bool, float], self.get("content_dict_bool_float")) @property def content_dict_bool_int(self) -> Dict[bool, int]: """Get the 'content_dict_bool_int' content from the message.""" assert self.is_set("content_dict_bool_int" ), "'content_dict_bool_int' content is not set." return cast(Dict[bool, int], self.get("content_dict_bool_int")) @property def content_dict_bool_str(self) -> Dict[bool, str]: """Get the 'content_dict_bool_str' content from the message.""" assert self.is_set("content_dict_bool_str" ), "'content_dict_bool_str' content is not set." return cast(Dict[bool, str], self.get("content_dict_bool_str")) @property def content_dict_int_bool(self) -> Dict[int, bool]: """Get the 'content_dict_int_bool' content from the message.""" assert self.is_set("content_dict_int_bool" ), "'content_dict_int_bool' content is not set." return cast(Dict[int, bool], self.get("content_dict_int_bool")) @property def content_dict_int_bytes(self) -> Dict[int, bytes]: """Get the 'content_dict_int_bytes' content from the message.""" assert self.is_set("content_dict_int_bytes" ), "'content_dict_int_bytes' content is not set." return cast(Dict[int, bytes], self.get("content_dict_int_bytes")) @property def content_dict_int_float(self) -> Dict[int, float]: """Get the 'content_dict_int_float' content from the message.""" assert self.is_set("content_dict_int_float" ), "'content_dict_int_float' content is not set." return cast(Dict[int, float], self.get("content_dict_int_float")) @property def content_dict_int_int(self) -> Dict[int, int]: """Get the 'content_dict_int_int' content from the message.""" assert self.is_set("content_dict_int_int" ), "'content_dict_int_int' content is not set." return cast(Dict[int, int], self.get("content_dict_int_int")) @property def content_dict_int_str(self) -> Dict[int, str]: """Get the 'content_dict_int_str' content from the message.""" assert self.is_set("content_dict_int_str" ), "'content_dict_int_str' content is not set." return cast(Dict[int, str], self.get("content_dict_int_str")) @property def content_dict_str_bool(self) -> Dict[str, bool]: """Get the 'content_dict_str_bool' content from the message.""" assert self.is_set("content_dict_str_bool" ), "'content_dict_str_bool' content is not set." return cast(Dict[str, bool], self.get("content_dict_str_bool")) @property def content_dict_str_bytes(self) -> Dict[str, bytes]: """Get the 'content_dict_str_bytes' content from the message.""" assert self.is_set("content_dict_str_bytes" ), "'content_dict_str_bytes' content is not set." return cast(Dict[str, bytes], self.get("content_dict_str_bytes")) @property def content_dict_str_float(self) -> Dict[str, float]: """Get the 'content_dict_str_float' content from the message.""" assert self.is_set("content_dict_str_float" ), "'content_dict_str_float' content is not set." return cast(Dict[str, float], self.get("content_dict_str_float")) @property def content_dict_str_int(self) -> Dict[str, int]: """Get the 'content_dict_str_int' content from the message.""" assert self.is_set("content_dict_str_int" ), "'content_dict_str_int' content is not set." return cast(Dict[str, int], self.get("content_dict_str_int")) @property def content_dict_str_str(self) -> Dict[str, str]: """Get the 'content_dict_str_str' content from the message.""" assert self.is_set("content_dict_str_str" ), "'content_dict_str_str' content is not set." return cast(Dict[str, str], self.get("content_dict_str_str")) @property def content_float(self) -> float: """Get the 'content_float' content from the message.""" assert self.is_set( "content_float"), "'content_float' content is not set." return cast(float, self.get("content_float")) @property def content_int(self) -> int: """Get the 'content_int' content from the message.""" assert self.is_set("content_int"), "'content_int' content is not set." return cast(int, self.get("content_int")) @property def content_list_bool(self) -> Tuple[bool, ...]: """Get the 'content_list_bool' content from the message.""" assert self.is_set( "content_list_bool"), "'content_list_bool' content is not set." return cast(Tuple[bool, ...], self.get("content_list_bool")) @property def content_list_bytes(self) -> Tuple[bytes, ...]: """Get the 'content_list_bytes' content from the message.""" assert self.is_set( "content_list_bytes"), "'content_list_bytes' content is not set." return cast(Tuple[bytes, ...], self.get("content_list_bytes")) @property def content_list_float(self) -> Tuple[float, ...]: """Get the 'content_list_float' content from the message.""" assert self.is_set( "content_list_float"), "'content_list_float' content is not set." return cast(Tuple[float, ...], self.get("content_list_float")) @property def content_list_int(self) -> Tuple[int, ...]: """Get the 'content_list_int' content from the message.""" assert self.is_set( "content_list_int"), "'content_list_int' content is not set." return cast(Tuple[int, ...], self.get("content_list_int")) @property def content_list_str(self) -> Tuple[str, ...]: """Get the 'content_list_str' content from the message.""" assert self.is_set( "content_list_str"), "'content_list_str' content is not set." return cast(Tuple[str, ...], self.get("content_list_str")) @property def content_o_bool(self) -> Optional[bool]: """Get the 'content_o_bool' content from the message.""" return cast(Optional[bool], self.get("content_o_bool")) @property def content_o_dict_str_int(self) -> Optional[Dict[str, int]]: """Get the 'content_o_dict_str_int' content from the message.""" return cast(Optional[Dict[str, int]], self.get("content_o_dict_str_int")) @property def content_o_list_bytes(self) -> Optional[Tuple[bytes, ...]]: """Get the 'content_o_list_bytes' content from the message.""" return cast(Optional[Tuple[bytes, ...]], self.get("content_o_list_bytes")) @property def content_o_set_int(self) -> Optional[FrozenSet[int]]: """Get the 'content_o_set_int' content from the message.""" return cast(Optional[FrozenSet[int]], self.get("content_o_set_int")) @property def content_set_bool(self) -> FrozenSet[bool]: """Get the 'content_set_bool' content from the message.""" assert self.is_set( "content_set_bool"), "'content_set_bool' content is not set." return cast(FrozenSet[bool], self.get("content_set_bool")) @property def content_set_bytes(self) -> FrozenSet[bytes]: """Get the 'content_set_bytes' content from the message.""" assert self.is_set( "content_set_bytes"), "'content_set_bytes' content is not set." return cast(FrozenSet[bytes], self.get("content_set_bytes")) @property def content_set_float(self) -> FrozenSet[float]: """Get the 'content_set_float' content from the message.""" assert self.is_set( "content_set_float"), "'content_set_float' content is not set." return cast(FrozenSet[float], self.get("content_set_float")) @property def content_set_int(self) -> FrozenSet[int]: """Get the 'content_set_int' content from the message.""" assert self.is_set( "content_set_int"), "'content_set_int' content is not set." return cast(FrozenSet[int], self.get("content_set_int")) @property def content_set_str(self) -> FrozenSet[str]: """Get the 'content_set_str' content from the message.""" assert self.is_set( "content_set_str"), "'content_set_str' content is not set." return cast(FrozenSet[str], self.get("content_set_str")) @property def content_str(self) -> str: """Get the 'content_str' content from the message.""" assert self.is_set("content_str"), "'content_str' content is not set." return cast(str, self.get("content_str")) @property def content_union_1( self, ) -> Union[bytes, int, float, bool, str, FrozenSet[int], Tuple[bool, ...], Dict[str, int]]: """Get the 'content_union_1' content from the message.""" assert self.is_set( "content_union_1"), "'content_union_1' content is not set." return cast( Union[bytes, int, float, bool, str, FrozenSet[int], Tuple[bool, ...], Dict[str, int], ], self.get("content_union_1"), ) @property def content_union_2( self, ) -> Union[FrozenSet[bytes], FrozenSet[int], FrozenSet[str], Tuple[ float, ...], Tuple[bool, ...], Tuple[bytes, ...], Dict[str, int], Dict[int, float], Dict[bool, bytes], ]: """Get the 'content_union_2' content from the message.""" assert self.is_set( "content_union_2"), "'content_union_2' content is not set." return cast( Union[FrozenSet[bytes], FrozenSet[int], FrozenSet[str], Tuple[float, ...], Tuple[bool, ...], Tuple[bytes, ...], Dict[str, int], Dict[int, float], Dict[bool, bytes], ], self.get("content_union_2"), ) def _is_consistent(self) -> bool: """Check that the message follows the t_protocol_no_ct protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == TProtocolNoCtMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == TProtocolNoCtMessage.Performative.PERFORMATIVE_PT: expected_nb_of_contents = 5 assert ( type(self.content_bytes) == bytes ), "Invalid type for content 'content_bytes'. Expected 'bytes'. Found '{}'.".format( type(self.content_bytes)) assert ( type(self.content_int) == int ), "Invalid type for content 'content_int'. Expected 'int'. Found '{}'.".format( type(self.content_int)) assert ( type(self.content_float) == float ), "Invalid type for content 'content_float'. Expected 'float'. Found '{}'.".format( type(self.content_float)) assert ( type(self.content_bool) == bool ), "Invalid type for content 'content_bool'. Expected 'bool'. Found '{}'.".format( type(self.content_bool)) assert ( type(self.content_str) == str ), "Invalid type for content 'content_str'. Expected 'str'. Found '{}'.".format( type(self.content_str)) elif (self.performative == TProtocolNoCtMessage.Performative.PERFORMATIVE_PCT): expected_nb_of_contents = 10 assert ( type(self.content_set_bytes) == frozenset ), "Invalid type for content 'content_set_bytes'. Expected 'frozenset'. Found '{}'.".format( type(self.content_set_bytes)) assert all( type(element) == bytes for element in self.content_set_bytes ), "Invalid type for frozenset elements in content 'content_set_bytes'. Expected 'bytes'." assert ( type(self.content_set_int) == frozenset ), "Invalid type for content 'content_set_int'. Expected 'frozenset'. Found '{}'.".format( type(self.content_set_int)) assert all( type(element) == int for element in self.content_set_int ), "Invalid type for frozenset elements in content 'content_set_int'. Expected 'int'." assert ( type(self.content_set_float) == frozenset ), "Invalid type for content 'content_set_float'. Expected 'frozenset'. Found '{}'.".format( type(self.content_set_float)) assert all( type(element) == float for element in self.content_set_float ), "Invalid type for frozenset elements in content 'content_set_float'. Expected 'float'." assert ( type(self.content_set_bool) == frozenset ), "Invalid type for content 'content_set_bool'. Expected 'frozenset'. Found '{}'.".format( type(self.content_set_bool)) assert all( type(element) == bool for element in self.content_set_bool ), "Invalid type for frozenset elements in content 'content_set_bool'. Expected 'bool'." assert ( type(self.content_set_str) == frozenset ), "Invalid type for content 'content_set_str'. Expected 'frozenset'. Found '{}'.".format( type(self.content_set_str)) assert all( type(element) == str for element in self.content_set_str ), "Invalid type for frozenset elements in content 'content_set_str'. Expected 'str'." assert ( type(self.content_list_bytes) == tuple ), "Invalid type for content 'content_list_bytes'. Expected 'tuple'. Found '{}'.".format( type(self.content_list_bytes)) assert all( type(element) == bytes for element in self.content_list_bytes ), "Invalid type for tuple elements in content 'content_list_bytes'. Expected 'bytes'." assert ( type(self.content_list_int) == tuple ), "Invalid type for content 'content_list_int'. Expected 'tuple'. Found '{}'.".format( type(self.content_list_int)) assert all( type(element) == int for element in self.content_list_int ), "Invalid type for tuple elements in content 'content_list_int'. Expected 'int'." assert ( type(self.content_list_float) == tuple ), "Invalid type for content 'content_list_float'. Expected 'tuple'. Found '{}'.".format( type(self.content_list_float)) assert all( type(element) == float for element in self.content_list_float ), "Invalid type for tuple elements in content 'content_list_float'. Expected 'float'." assert ( type(self.content_list_bool) == tuple ), "Invalid type for content 'content_list_bool'. Expected 'tuple'. Found '{}'.".format( type(self.content_list_bool)) assert all( type(element) == bool for element in self.content_list_bool ), "Invalid type for tuple elements in content 'content_list_bool'. Expected 'bool'." assert ( type(self.content_list_str) == tuple ), "Invalid type for content 'content_list_str'. Expected 'tuple'. Found '{}'.".format( type(self.content_list_str)) assert all( type(element) == str for element in self.content_list_str ), "Invalid type for tuple elements in content 'content_list_str'. Expected 'str'." elif (self.performative == TProtocolNoCtMessage.Performative.PERFORMATIVE_PMT): expected_nb_of_contents = 15 assert ( type(self.content_dict_int_bytes) == dict ), "Invalid type for content 'content_dict_int_bytes'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_int_bytes)) for ( key_of_content_dict_int_bytes, value_of_content_dict_int_bytes, ) in self.content_dict_int_bytes.items(): assert ( type(key_of_content_dict_int_bytes) == int ), "Invalid type for dictionary keys in content 'content_dict_int_bytes'. Expected 'int'. Found '{}'.".format( type(key_of_content_dict_int_bytes)) assert ( type(value_of_content_dict_int_bytes) == bytes ), "Invalid type for dictionary values in content 'content_dict_int_bytes'. Expected 'bytes'. Found '{}'.".format( type(value_of_content_dict_int_bytes)) assert ( type(self.content_dict_int_int) == dict ), "Invalid type for content 'content_dict_int_int'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_int_int)) for ( key_of_content_dict_int_int, value_of_content_dict_int_int, ) in self.content_dict_int_int.items(): assert ( type(key_of_content_dict_int_int) == int ), "Invalid type for dictionary keys in content 'content_dict_int_int'. Expected 'int'. Found '{}'.".format( type(key_of_content_dict_int_int)) assert ( type(value_of_content_dict_int_int) == int ), "Invalid type for dictionary values in content 'content_dict_int_int'. Expected 'int'. Found '{}'.".format( type(value_of_content_dict_int_int)) assert ( type(self.content_dict_int_float) == dict ), "Invalid type for content 'content_dict_int_float'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_int_float)) for ( key_of_content_dict_int_float, value_of_content_dict_int_float, ) in self.content_dict_int_float.items(): assert ( type(key_of_content_dict_int_float) == int ), "Invalid type for dictionary keys in content 'content_dict_int_float'. Expected 'int'. Found '{}'.".format( type(key_of_content_dict_int_float)) assert ( type(value_of_content_dict_int_float) == float ), "Invalid type for dictionary values in content 'content_dict_int_float'. Expected 'float'. Found '{}'.".format( type(value_of_content_dict_int_float)) assert ( type(self.content_dict_int_bool) == dict ), "Invalid type for content 'content_dict_int_bool'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_int_bool)) for ( key_of_content_dict_int_bool, value_of_content_dict_int_bool, ) in self.content_dict_int_bool.items(): assert ( type(key_of_content_dict_int_bool) == int ), "Invalid type for dictionary keys in content 'content_dict_int_bool'. Expected 'int'. Found '{}'.".format( type(key_of_content_dict_int_bool)) assert ( type(value_of_content_dict_int_bool) == bool ), "Invalid type for dictionary values in content 'content_dict_int_bool'. Expected 'bool'. Found '{}'.".format( type(value_of_content_dict_int_bool)) assert ( type(self.content_dict_int_str) == dict ), "Invalid type for content 'content_dict_int_str'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_int_str)) for ( key_of_content_dict_int_str, value_of_content_dict_int_str, ) in self.content_dict_int_str.items(): assert ( type(key_of_content_dict_int_str) == int ), "Invalid type for dictionary keys in content 'content_dict_int_str'. Expected 'int'. Found '{}'.".format( type(key_of_content_dict_int_str)) assert ( type(value_of_content_dict_int_str) == str ), "Invalid type for dictionary values in content 'content_dict_int_str'. Expected 'str'. Found '{}'.".format( type(value_of_content_dict_int_str)) assert ( type(self.content_dict_bool_bytes) == dict ), "Invalid type for content 'content_dict_bool_bytes'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_bool_bytes)) for ( key_of_content_dict_bool_bytes, value_of_content_dict_bool_bytes, ) in self.content_dict_bool_bytes.items(): assert ( type(key_of_content_dict_bool_bytes) == bool ), "Invalid type for dictionary keys in content 'content_dict_bool_bytes'. Expected 'bool'. Found '{}'.".format( type(key_of_content_dict_bool_bytes)) assert ( type(value_of_content_dict_bool_bytes) == bytes ), "Invalid type for dictionary values in content 'content_dict_bool_bytes'. Expected 'bytes'. Found '{}'.".format( type(value_of_content_dict_bool_bytes)) assert ( type(self.content_dict_bool_int) == dict ), "Invalid type for content 'content_dict_bool_int'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_bool_int)) for ( key_of_content_dict_bool_int, value_of_content_dict_bool_int, ) in self.content_dict_bool_int.items(): assert ( type(key_of_content_dict_bool_int) == bool ), "Invalid type for dictionary keys in content 'content_dict_bool_int'. Expected 'bool'. Found '{}'.".format( type(key_of_content_dict_bool_int)) assert ( type(value_of_content_dict_bool_int) == int ), "Invalid type for dictionary values in content 'content_dict_bool_int'. Expected 'int'. Found '{}'.".format( type(value_of_content_dict_bool_int)) assert ( type(self.content_dict_bool_float) == dict ), "Invalid type for content 'content_dict_bool_float'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_bool_float)) for ( key_of_content_dict_bool_float, value_of_content_dict_bool_float, ) in self.content_dict_bool_float.items(): assert ( type(key_of_content_dict_bool_float) == bool ), "Invalid type for dictionary keys in content 'content_dict_bool_float'. Expected 'bool'. Found '{}'.".format( type(key_of_content_dict_bool_float)) assert ( type(value_of_content_dict_bool_float) == float ), "Invalid type for dictionary values in content 'content_dict_bool_float'. Expected 'float'. Found '{}'.".format( type(value_of_content_dict_bool_float)) assert ( type(self.content_dict_bool_bool) == dict ), "Invalid type for content 'content_dict_bool_bool'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_bool_bool)) for ( key_of_content_dict_bool_bool, value_of_content_dict_bool_bool, ) in self.content_dict_bool_bool.items(): assert ( type(key_of_content_dict_bool_bool) == bool ), "Invalid type for dictionary keys in content 'content_dict_bool_bool'. Expected 'bool'. Found '{}'.".format( type(key_of_content_dict_bool_bool)) assert ( type(value_of_content_dict_bool_bool) == bool ), "Invalid type for dictionary values in content 'content_dict_bool_bool'. Expected 'bool'. Found '{}'.".format( type(value_of_content_dict_bool_bool)) assert ( type(self.content_dict_bool_str) == dict ), "Invalid type for content 'content_dict_bool_str'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_bool_str)) for ( key_of_content_dict_bool_str, value_of_content_dict_bool_str, ) in self.content_dict_bool_str.items(): assert ( type(key_of_content_dict_bool_str) == bool ), "Invalid type for dictionary keys in content 'content_dict_bool_str'. Expected 'bool'. Found '{}'.".format( type(key_of_content_dict_bool_str)) assert ( type(value_of_content_dict_bool_str) == str ), "Invalid type for dictionary values in content 'content_dict_bool_str'. Expected 'str'. Found '{}'.".format( type(value_of_content_dict_bool_str)) assert ( type(self.content_dict_str_bytes) == dict ), "Invalid type for content 'content_dict_str_bytes'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_str_bytes)) for ( key_of_content_dict_str_bytes, value_of_content_dict_str_bytes, ) in self.content_dict_str_bytes.items(): assert ( type(key_of_content_dict_str_bytes) == str ), "Invalid type for dictionary keys in content 'content_dict_str_bytes'. Expected 'str'. Found '{}'.".format( type(key_of_content_dict_str_bytes)) assert ( type(value_of_content_dict_str_bytes) == bytes ), "Invalid type for dictionary values in content 'content_dict_str_bytes'. Expected 'bytes'. Found '{}'.".format( type(value_of_content_dict_str_bytes)) assert ( type(self.content_dict_str_int) == dict ), "Invalid type for content 'content_dict_str_int'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_str_int)) for ( key_of_content_dict_str_int, value_of_content_dict_str_int, ) in self.content_dict_str_int.items(): assert ( type(key_of_content_dict_str_int) == str ), "Invalid type for dictionary keys in content 'content_dict_str_int'. Expected 'str'. Found '{}'.".format( type(key_of_content_dict_str_int)) assert ( type(value_of_content_dict_str_int) == int ), "Invalid type for dictionary values in content 'content_dict_str_int'. Expected 'int'. Found '{}'.".format( type(value_of_content_dict_str_int)) assert ( type(self.content_dict_str_float) == dict ), "Invalid type for content 'content_dict_str_float'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_str_float)) for ( key_of_content_dict_str_float, value_of_content_dict_str_float, ) in self.content_dict_str_float.items(): assert ( type(key_of_content_dict_str_float) == str ), "Invalid type for dictionary keys in content 'content_dict_str_float'. Expected 'str'. Found '{}'.".format( type(key_of_content_dict_str_float)) assert ( type(value_of_content_dict_str_float) == float ), "Invalid type for dictionary values in content 'content_dict_str_float'. Expected 'float'. Found '{}'.".format( type(value_of_content_dict_str_float)) assert ( type(self.content_dict_str_bool) == dict ), "Invalid type for content 'content_dict_str_bool'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_str_bool)) for ( key_of_content_dict_str_bool, value_of_content_dict_str_bool, ) in self.content_dict_str_bool.items(): assert ( type(key_of_content_dict_str_bool) == str ), "Invalid type for dictionary keys in content 'content_dict_str_bool'. Expected 'str'. Found '{}'.".format( type(key_of_content_dict_str_bool)) assert ( type(value_of_content_dict_str_bool) == bool ), "Invalid type for dictionary values in content 'content_dict_str_bool'. Expected 'bool'. Found '{}'.".format( type(value_of_content_dict_str_bool)) assert ( type(self.content_dict_str_str) == dict ), "Invalid type for content 'content_dict_str_str'. Expected 'dict'. Found '{}'.".format( type(self.content_dict_str_str)) for ( key_of_content_dict_str_str, value_of_content_dict_str_str, ) in self.content_dict_str_str.items(): assert ( type(key_of_content_dict_str_str) == str ), "Invalid type for dictionary keys in content 'content_dict_str_str'. Expected 'str'. Found '{}'.".format( type(key_of_content_dict_str_str)) assert ( type(value_of_content_dict_str_str) == str ), "Invalid type for dictionary values in content 'content_dict_str_str'. Expected 'str'. Found '{}'.".format( type(value_of_content_dict_str_str)) elif self.performative == TProtocolNoCtMessage.Performative.PERFORMATIVE_MT: expected_nb_of_contents = 2 assert ( type(self.content_union_1) == bool or type(self.content_union_1) == bytes or type(self.content_union_1) == dict or type(self.content_union_1) == float or type(self.content_union_1) == frozenset or type(self.content_union_1) == int or type(self.content_union_1) == str or type(self.content_union_1) == tuple ), "Invalid type for content 'content_union_1'. Expected either of '['bool', 'bytes', 'dict', 'float', 'frozenset', 'int', 'str', 'tuple']'. Found '{}'.".format( type(self.content_union_1)) if type(self.content_union_1) == frozenset: assert all( type(element) == int for element in self.content_union_1 ), "Invalid type for elements of content 'content_union_1'. Expected 'int'." if type(self.content_union_1) == tuple: assert all( type(element) == bool for element in self.content_union_1 ), "Invalid type for tuple elements in content 'content_union_1'. Expected 'bool'." if type(self.content_union_1) == dict: for ( key_of_content_union_1, value_of_content_union_1, ) in self.content_union_1.items(): assert ( type(key_of_content_union_1) == str and type(value_of_content_union_1) == int ), "Invalid type for dictionary key, value in content 'content_union_1'. Expected 'str', 'int'." assert ( type(self.content_union_2) == dict or type(self.content_union_2) == frozenset or type(self.content_union_2) == tuple ), "Invalid type for content 'content_union_2'. Expected either of '['dict', 'frozenset', 'tuple']'. Found '{}'.".format( type(self.content_union_2)) if type(self.content_union_2) == frozenset: assert ( all( type(element) == bytes for element in self.content_union_2) or all( type(element) == int for element in self.content_union_2) or all( type(element) == str for element in self.content_union_2) ), "Invalid type for frozenset elements in content 'content_union_2'. Expected either 'bytes' or 'int' or 'str'." if type(self.content_union_2) == tuple: assert ( all( type(element) == bool for element in self.content_union_2) or all( type(element) == bytes for element in self.content_union_2) or all( type(element) == float for element in self.content_union_2) ), "Invalid type for tuple elements in content 'content_union_2'. Expected either 'bool' or 'bytes' or 'float'." if type(self.content_union_2) == dict: for ( key_of_content_union_2, value_of_content_union_2, ) in self.content_union_2.items(): assert ( (type(key_of_content_union_2) == bool and type(value_of_content_union_2) == bytes) or (type(key_of_content_union_2) == int and type(value_of_content_union_2) == float) or (type(key_of_content_union_2) == str and type(value_of_content_union_2) == int) ), "Invalid type for dictionary key, value in content 'content_union_2'. Expected 'bool','bytes' or 'int','float' or 'str','int'." elif self.performative == TProtocolNoCtMessage.Performative.PERFORMATIVE_O: expected_nb_of_contents = 0 if self.is_set("content_o_bool"): expected_nb_of_contents += 1 content_o_bool = cast(bool, self.content_o_bool) assert ( type(content_o_bool) == bool ), "Invalid type for content 'content_o_bool'. Expected 'bool'. Found '{}'.".format( type(content_o_bool)) if self.is_set("content_o_set_int"): expected_nb_of_contents += 1 content_o_set_int = cast(FrozenSet[int], self.content_o_set_int) assert ( type(content_o_set_int) == frozenset ), "Invalid type for content 'content_o_set_int'. Expected 'frozenset'. Found '{}'.".format( type(content_o_set_int)) assert all( type(element) == int for element in content_o_set_int ), "Invalid type for frozenset elements in content 'content_o_set_int'. Expected 'int'." if self.is_set("content_o_list_bytes"): expected_nb_of_contents += 1 content_o_list_bytes = cast(Tuple[bytes, ...], self.content_o_list_bytes) assert ( type(content_o_list_bytes) == tuple ), "Invalid type for content 'content_o_list_bytes'. Expected 'tuple'. Found '{}'.".format( type(content_o_list_bytes)) assert all( type(element) == bytes for element in content_o_list_bytes ), "Invalid type for tuple elements in content 'content_o_list_bytes'. Expected 'bytes'." if self.is_set("content_o_dict_str_int"): expected_nb_of_contents += 1 content_o_dict_str_int = cast(Dict[str, int], self.content_o_dict_str_int) assert ( type(content_o_dict_str_int) == dict ), "Invalid type for content 'content_o_dict_str_int'. Expected 'dict'. Found '{}'.".format( type(content_o_dict_str_int)) for ( key_of_content_o_dict_str_int, value_of_content_o_dict_str_int, ) in content_o_dict_str_int.items(): assert ( type(key_of_content_o_dict_str_int) == str ), "Invalid type for dictionary keys in content 'content_o_dict_str_int'. Expected 'str'. Found '{}'.".format( type(key_of_content_o_dict_str_int)) assert ( type(value_of_content_o_dict_str_int) == int ), "Invalid type for dictionary values in content 'content_o_dict_str_int'. Expected 'int'. Found '{}'.".format( type(value_of_content_o_dict_str_int)) elif (self.performative == TProtocolNoCtMessage.Performative. PERFORMATIVE_EMPTY_CONTENTS): expected_nb_of_contents = 0 # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class GymMessage(Message): """A protocol for interacting with a gym connection.""" protocol_id = ProtocolId.from_str("fetchai/gym:0.4.0") AnyObject = CustomAnyObject class Performative(Enum): """Performatives for the gym protocol.""" ACT = "act" CLOSE = "close" PERCEPT = "percept" RESET = "reset" STATUS = "status" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of GymMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=GymMessage.Performative(performative), **kwargs, ) self._performatives = {"act", "close", "percept", "reset", "status"} @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(GymMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def action(self) -> CustomAnyObject: """Get the 'action' content from the message.""" assert self.is_set("action"), "'action' content is not set." return cast(CustomAnyObject, self.get("action")) @property def content(self) -> Dict[str, str]: """Get the 'content' content from the message.""" assert self.is_set("content"), "'content' content is not set." return cast(Dict[str, str], self.get("content")) @property def done(self) -> bool: """Get the 'done' content from the message.""" assert self.is_set("done"), "'done' content is not set." return cast(bool, self.get("done")) @property def info(self) -> CustomAnyObject: """Get the 'info' content from the message.""" assert self.is_set("info"), "'info' content is not set." return cast(CustomAnyObject, self.get("info")) @property def observation(self) -> CustomAnyObject: """Get the 'observation' content from the message.""" assert self.is_set("observation"), "'observation' content is not set." return cast(CustomAnyObject, self.get("observation")) @property def reward(self) -> float: """Get the 'reward' content from the message.""" assert self.is_set("reward"), "'reward' content is not set." return cast(float, self.get("reward")) @property def step_id(self) -> int: """Get the 'step_id' content from the message.""" assert self.is_set("step_id"), "'step_id' content is not set." return cast(int, self.get("step_id")) def _is_consistent(self) -> bool: """Check that the message follows the gym protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == GymMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == GymMessage.Performative.ACT: expected_nb_of_contents = 2 assert ( type(self.action) == CustomAnyObject ), "Invalid type for content 'action'. Expected 'AnyObject'. Found '{}'.".format( type(self.action)) assert ( type(self.step_id) == int ), "Invalid type for content 'step_id'. Expected 'int'. Found '{}'.".format( type(self.step_id)) elif self.performative == GymMessage.Performative.PERCEPT: expected_nb_of_contents = 5 assert ( type(self.step_id) == int ), "Invalid type for content 'step_id'. Expected 'int'. Found '{}'.".format( type(self.step_id)) assert ( type(self.observation) == CustomAnyObject ), "Invalid type for content 'observation'. Expected 'AnyObject'. Found '{}'.".format( type(self.observation)) assert ( type(self.reward) == float ), "Invalid type for content 'reward'. Expected 'float'. Found '{}'.".format( type(self.reward)) assert ( type(self.done) == bool ), "Invalid type for content 'done'. Expected 'bool'. Found '{}'.".format( type(self.done)) assert ( type(self.info) == CustomAnyObject ), "Invalid type for content 'info'. Expected 'AnyObject'. Found '{}'.".format( type(self.info)) elif self.performative == GymMessage.Performative.STATUS: expected_nb_of_contents = 1 assert ( type(self.content) == dict ), "Invalid type for content 'content'. Expected 'dict'. Found '{}'.".format( type(self.content)) for key_of_content, value_of_content in self.content.items(): assert ( type(key_of_content) == str ), "Invalid type for dictionary keys in content 'content'. Expected 'str'. Found '{}'.".format( type(key_of_content)) assert ( type(value_of_content) == str ), "Invalid type for dictionary values in content 'content'. Expected 'str'. Found '{}'.".format( type(value_of_content)) elif self.performative == GymMessage.Performative.RESET: expected_nb_of_contents = 0 elif self.performative == GymMessage.Performative.CLOSE: expected_nb_of_contents = 0 # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class MlTradeMessage(Message): """A protocol for trading data for training and prediction purposes.""" protocol_id = ProtocolId.from_str("fetchai/ml_trade:0.4.0") Description = CustomDescription Query = CustomQuery class Performative(Enum): """Performatives for the ml_trade protocol.""" ACCEPT = "accept" CFP = "cfp" DATA = "data" TERMS = "terms" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of MlTradeMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=MlTradeMessage.Performative(performative), **kwargs, ) self._performatives = {"accept", "cfp", "data", "terms"} @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(MlTradeMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def payload(self) -> bytes: """Get the 'payload' content from the message.""" assert self.is_set("payload"), "'payload' content is not set." return cast(bytes, self.get("payload")) @property def query(self) -> CustomQuery: """Get the 'query' content from the message.""" assert self.is_set("query"), "'query' content is not set." return cast(CustomQuery, self.get("query")) @property def terms(self) -> CustomDescription: """Get the 'terms' content from the message.""" assert self.is_set("terms"), "'terms' content is not set." return cast(CustomDescription, self.get("terms")) @property def tx_digest(self) -> str: """Get the 'tx_digest' content from the message.""" assert self.is_set("tx_digest"), "'tx_digest' content is not set." return cast(str, self.get("tx_digest")) def _is_consistent(self) -> bool: """Check that the message follows the ml_trade protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == MlTradeMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == MlTradeMessage.Performative.CFP: expected_nb_of_contents = 1 assert ( type(self.query) == CustomQuery ), "Invalid type for content 'query'. Expected 'Query'. Found '{}'.".format( type(self.query)) elif self.performative == MlTradeMessage.Performative.TERMS: expected_nb_of_contents = 1 assert ( type(self.terms) == CustomDescription ), "Invalid type for content 'terms'. Expected 'Description'. Found '{}'.".format( type(self.terms)) elif self.performative == MlTradeMessage.Performative.ACCEPT: expected_nb_of_contents = 2 assert ( type(self.terms) == CustomDescription ), "Invalid type for content 'terms'. Expected 'Description'. Found '{}'.".format( type(self.terms)) assert ( type(self.tx_digest) == str ), "Invalid type for content 'tx_digest'. Expected 'str'. Found '{}'.".format( type(self.tx_digest)) elif self.performative == MlTradeMessage.Performative.DATA: expected_nb_of_contents = 2 assert ( type(self.terms) == CustomDescription ), "Invalid type for content 'terms'. Expected 'Description'. Found '{}'.".format( type(self.terms)) assert ( type(self.payload) == bytes ), "Invalid type for content 'payload'. Expected 'bytes'. Found '{}'.".format( type(self.payload)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class TacMessage(Message): """The tac protocol implements the messages an AEA needs to participate in the TAC.""" protocol_id = ProtocolId.from_str("fetchai/tac:0.5.0") ErrorCode = CustomErrorCode class Performative(Enum): """Performatives for the tac protocol.""" CANCELLED = "cancelled" GAME_DATA = "game_data" REGISTER = "register" TAC_ERROR = "tac_error" TRANSACTION = "transaction" TRANSACTION_CONFIRMATION = "transaction_confirmation" UNREGISTER = "unregister" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of TacMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=TacMessage.Performative(performative), **kwargs, ) self._performatives = { "cancelled", "game_data", "register", "tac_error", "transaction", "transaction_confirmation", "unregister", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(TacMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def agent_addr_to_name(self) -> Dict[str, str]: """Get the 'agent_addr_to_name' content from the message.""" assert self.is_set( "agent_addr_to_name"), "'agent_addr_to_name' content is not set." return cast(Dict[str, str], self.get("agent_addr_to_name")) @property def agent_name(self) -> str: """Get the 'agent_name' content from the message.""" assert self.is_set("agent_name"), "'agent_name' content is not set." return cast(str, self.get("agent_name")) @property def amount_by_currency_id(self) -> Dict[str, int]: """Get the 'amount_by_currency_id' content from the message.""" assert self.is_set("amount_by_currency_id" ), "'amount_by_currency_id' content is not set." return cast(Dict[str, int], self.get("amount_by_currency_id")) @property def counterparty_address(self) -> str: """Get the 'counterparty_address' content from the message.""" assert self.is_set("counterparty_address" ), "'counterparty_address' content is not set." return cast(str, self.get("counterparty_address")) @property def counterparty_signature(self) -> str: """Get the 'counterparty_signature' content from the message.""" assert self.is_set("counterparty_signature" ), "'counterparty_signature' content is not set." return cast(str, self.get("counterparty_signature")) @property def currency_id_to_name(self) -> Dict[str, str]: """Get the 'currency_id_to_name' content from the message.""" assert self.is_set( "currency_id_to_name"), "'currency_id_to_name' content is not set." return cast(Dict[str, str], self.get("currency_id_to_name")) @property def error_code(self) -> CustomErrorCode: """Get the 'error_code' content from the message.""" assert self.is_set("error_code"), "'error_code' content is not set." return cast(CustomErrorCode, self.get("error_code")) @property def exchange_params_by_currency_id(self) -> Dict[str, float]: """Get the 'exchange_params_by_currency_id' content from the message.""" assert self.is_set( "exchange_params_by_currency_id" ), "'exchange_params_by_currency_id' content is not set." return cast(Dict[str, float], self.get("exchange_params_by_currency_id")) @property def fee_by_currency_id(self) -> Dict[str, int]: """Get the 'fee_by_currency_id' content from the message.""" assert self.is_set( "fee_by_currency_id"), "'fee_by_currency_id' content is not set." return cast(Dict[str, int], self.get("fee_by_currency_id")) @property def good_id_to_name(self) -> Dict[str, str]: """Get the 'good_id_to_name' content from the message.""" assert self.is_set( "good_id_to_name"), "'good_id_to_name' content is not set." return cast(Dict[str, str], self.get("good_id_to_name")) @property def info(self) -> Optional[Dict[str, str]]: """Get the 'info' content from the message.""" return cast(Optional[Dict[str, str]], self.get("info")) @property def ledger_id(self) -> str: """Get the 'ledger_id' content from the message.""" assert self.is_set("ledger_id"), "'ledger_id' content is not set." return cast(str, self.get("ledger_id")) @property def nonce(self) -> str: """Get the 'nonce' content from the message.""" assert self.is_set("nonce"), "'nonce' content is not set." return cast(str, self.get("nonce")) @property def quantities_by_good_id(self) -> Dict[str, int]: """Get the 'quantities_by_good_id' content from the message.""" assert self.is_set("quantities_by_good_id" ), "'quantities_by_good_id' content is not set." return cast(Dict[str, int], self.get("quantities_by_good_id")) @property def sender_address(self) -> str: """Get the 'sender_address' content from the message.""" assert self.is_set( "sender_address"), "'sender_address' content is not set." return cast(str, self.get("sender_address")) @property def sender_signature(self) -> str: """Get the 'sender_signature' content from the message.""" assert self.is_set( "sender_signature"), "'sender_signature' content is not set." return cast(str, self.get("sender_signature")) @property def transaction_id(self) -> str: """Get the 'transaction_id' content from the message.""" assert self.is_set( "transaction_id"), "'transaction_id' content is not set." return cast(str, self.get("transaction_id")) @property def utility_params_by_good_id(self) -> Dict[str, float]: """Get the 'utility_params_by_good_id' content from the message.""" assert self.is_set("utility_params_by_good_id" ), "'utility_params_by_good_id' content is not set." return cast(Dict[str, float], self.get("utility_params_by_good_id")) @property def version_id(self) -> str: """Get the 'version_id' content from the message.""" assert self.is_set("version_id"), "'version_id' content is not set." return cast(str, self.get("version_id")) def _is_consistent(self) -> bool: """Check that the message follows the tac protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == TacMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == TacMessage.Performative.REGISTER: expected_nb_of_contents = 1 assert ( type(self.agent_name) == str ), "Invalid type for content 'agent_name'. Expected 'str'. Found '{}'.".format( type(self.agent_name)) elif self.performative == TacMessage.Performative.UNREGISTER: expected_nb_of_contents = 0 elif self.performative == TacMessage.Performative.TRANSACTION: expected_nb_of_contents = 10 assert ( type(self.transaction_id) == str ), "Invalid type for content 'transaction_id'. Expected 'str'. Found '{}'.".format( type(self.transaction_id)) assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id)) assert ( type(self.sender_address) == str ), "Invalid type for content 'sender_address'. Expected 'str'. Found '{}'.".format( type(self.sender_address)) assert ( type(self.counterparty_address) == str ), "Invalid type for content 'counterparty_address'. Expected 'str'. Found '{}'.".format( type(self.counterparty_address)) assert ( type(self.amount_by_currency_id) == dict ), "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id)) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): assert ( type(key_of_amount_by_currency_id) == str ), "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id)) assert ( type(value_of_amount_by_currency_id) == int ), "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id)) assert ( type(self.fee_by_currency_id) == dict ), "Invalid type for content 'fee_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.fee_by_currency_id)) for ( key_of_fee_by_currency_id, value_of_fee_by_currency_id, ) in self.fee_by_currency_id.items(): assert ( type(key_of_fee_by_currency_id) == str ), "Invalid type for dictionary keys in content 'fee_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_fee_by_currency_id)) assert ( type(value_of_fee_by_currency_id) == int ), "Invalid type for dictionary values in content 'fee_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_fee_by_currency_id)) assert ( type(self.quantities_by_good_id) == dict ), "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id)) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): assert ( type(key_of_quantities_by_good_id) == str ), "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id)) assert ( type(value_of_quantities_by_good_id) == int ), "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id)) assert ( type(self.nonce) == str ), "Invalid type for content 'nonce'. Expected 'str'. Found '{}'.".format( type(self.nonce)) assert ( type(self.sender_signature) == str ), "Invalid type for content 'sender_signature'. Expected 'str'. Found '{}'.".format( type(self.sender_signature)) assert ( type(self.counterparty_signature) == str ), "Invalid type for content 'counterparty_signature'. Expected 'str'. Found '{}'.".format( type(self.counterparty_signature)) elif self.performative == TacMessage.Performative.CANCELLED: expected_nb_of_contents = 0 elif self.performative == TacMessage.Performative.GAME_DATA: expected_nb_of_contents = 9 assert ( type(self.amount_by_currency_id) == dict ), "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id)) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): assert ( type(key_of_amount_by_currency_id) == str ), "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id)) assert ( type(value_of_amount_by_currency_id) == int ), "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id)) assert ( type(self.exchange_params_by_currency_id) == dict ), "Invalid type for content 'exchange_params_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.exchange_params_by_currency_id)) for ( key_of_exchange_params_by_currency_id, value_of_exchange_params_by_currency_id, ) in self.exchange_params_by_currency_id.items(): assert ( type(key_of_exchange_params_by_currency_id) == str ), "Invalid type for dictionary keys in content 'exchange_params_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_exchange_params_by_currency_id)) assert ( type(value_of_exchange_params_by_currency_id) == float ), "Invalid type for dictionary values in content 'exchange_params_by_currency_id'. Expected 'float'. Found '{}'.".format( type(value_of_exchange_params_by_currency_id)) assert ( type(self.quantities_by_good_id) == dict ), "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id)) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): assert ( type(key_of_quantities_by_good_id) == str ), "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id)) assert ( type(value_of_quantities_by_good_id) == int ), "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id)) assert ( type(self.utility_params_by_good_id) == dict ), "Invalid type for content 'utility_params_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.utility_params_by_good_id)) for ( key_of_utility_params_by_good_id, value_of_utility_params_by_good_id, ) in self.utility_params_by_good_id.items(): assert ( type(key_of_utility_params_by_good_id) == str ), "Invalid type for dictionary keys in content 'utility_params_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_utility_params_by_good_id)) assert ( type(value_of_utility_params_by_good_id) == float ), "Invalid type for dictionary values in content 'utility_params_by_good_id'. Expected 'float'. Found '{}'.".format( type(value_of_utility_params_by_good_id)) assert ( type(self.fee_by_currency_id) == dict ), "Invalid type for content 'fee_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.fee_by_currency_id)) for ( key_of_fee_by_currency_id, value_of_fee_by_currency_id, ) in self.fee_by_currency_id.items(): assert ( type(key_of_fee_by_currency_id) == str ), "Invalid type for dictionary keys in content 'fee_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_fee_by_currency_id)) assert ( type(value_of_fee_by_currency_id) == int ), "Invalid type for dictionary values in content 'fee_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_fee_by_currency_id)) assert ( type(self.agent_addr_to_name) == dict ), "Invalid type for content 'agent_addr_to_name'. Expected 'dict'. Found '{}'.".format( type(self.agent_addr_to_name)) for ( key_of_agent_addr_to_name, value_of_agent_addr_to_name, ) in self.agent_addr_to_name.items(): assert ( type(key_of_agent_addr_to_name) == str ), "Invalid type for dictionary keys in content 'agent_addr_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_agent_addr_to_name)) assert ( type(value_of_agent_addr_to_name) == str ), "Invalid type for dictionary values in content 'agent_addr_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_agent_addr_to_name)) assert ( type(self.currency_id_to_name) == dict ), "Invalid type for content 'currency_id_to_name'. Expected 'dict'. Found '{}'.".format( type(self.currency_id_to_name)) for ( key_of_currency_id_to_name, value_of_currency_id_to_name, ) in self.currency_id_to_name.items(): assert ( type(key_of_currency_id_to_name) == str ), "Invalid type for dictionary keys in content 'currency_id_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_currency_id_to_name)) assert ( type(value_of_currency_id_to_name) == str ), "Invalid type for dictionary values in content 'currency_id_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_currency_id_to_name)) assert ( type(self.good_id_to_name) == dict ), "Invalid type for content 'good_id_to_name'. Expected 'dict'. Found '{}'.".format( type(self.good_id_to_name)) for ( key_of_good_id_to_name, value_of_good_id_to_name, ) in self.good_id_to_name.items(): assert ( type(key_of_good_id_to_name) == str ), "Invalid type for dictionary keys in content 'good_id_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_good_id_to_name)) assert ( type(value_of_good_id_to_name) == str ), "Invalid type for dictionary values in content 'good_id_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_good_id_to_name)) assert ( type(self.version_id) == str ), "Invalid type for content 'version_id'. Expected 'str'. Found '{}'.".format( type(self.version_id)) if self.is_set("info"): expected_nb_of_contents += 1 info = cast(Dict[str, str], self.info) assert ( type(info) == dict ), "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(info)) for key_of_info, value_of_info in info.items(): assert ( type(key_of_info) == str ), "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info)) assert ( type(value_of_info) == str ), "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info)) elif self.performative == TacMessage.Performative.TRANSACTION_CONFIRMATION: expected_nb_of_contents = 3 assert ( type(self.transaction_id) == str ), "Invalid type for content 'transaction_id'. Expected 'str'. Found '{}'.".format( type(self.transaction_id)) assert ( type(self.amount_by_currency_id) == dict ), "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id)) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): assert ( type(key_of_amount_by_currency_id) == str ), "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id)) assert ( type(value_of_amount_by_currency_id) == int ), "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id)) assert ( type(self.quantities_by_good_id) == dict ), "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id)) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): assert ( type(key_of_quantities_by_good_id) == str ), "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id)) assert ( type(value_of_quantities_by_good_id) == int ), "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id)) elif self.performative == TacMessage.Performative.TAC_ERROR: expected_nb_of_contents = 1 assert ( type(self.error_code) == CustomErrorCode ), "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( type(self.error_code)) if self.is_set("info"): expected_nb_of_contents += 1 info = cast(Dict[str, str], self.info) assert ( type(info) == dict ), "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(info)) for key_of_info, value_of_info in info.items(): assert ( type(key_of_info) == str ), "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info)) assert ( type(value_of_info) == str ), "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
def test_soef(): # First run OEF in a separate terminal: python scripts/oef/launch.py -c ./scripts/oef/launch_config.json crypto = FetchAICrypto() # create the connection and multiplexer objects soef_connection = SOEFConnection( api_key="TwiCIriSl0mLahw17pyqoA", soef_addr="soef.fetch.ai", soef_port=9002, address=crypto.address, ) multiplexer = Multiplexer([soef_connection]) try: # Set the multiplexer running in a different thread t = Thread(target=multiplexer.connect) t.start() time.sleep(3.0) # register a service with location attr_service_name = Attribute("service_name", str, True, "The name of the service.") attr_location = Attribute( "location", Location, True, "The location where the service is provided.") service_location_model = DataModel( "location_service", [attr_service_name, attr_location], "A data model to describe location of a service.", ) service_name = "train" service_location = Location(52.2057092, 2.1183431) service_instance = { "service_name": service_name, "location": service_location } service_description = Description(service_instance, data_model=service_location_model) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, service_description=service_description, ) message_b = OefSearchSerializer().encode(message) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=ProtocolId.from_str("fetchai/oef_search:0.1.0"), message=message_b, ) logger.info( "Registering service={} at location=({},{}) by agent={}".format( service_name, service_location.latitude, service_location.longitude, crypto.address, )) multiplexer.put(envelope) # find agents near the previously registered service radius = 0.1 matches_my_service_name = Constraint( "service_name", ConstraintType("==", service_name)) close_to_my_service = Constraint( "location", ConstraintType("distance", (service_location, radius))) closeness_query = Query([matches_my_service_name, close_to_my_service], model=service_location_model) message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, query=closeness_query, ) message_b = OefSearchSerializer().encode(message) envelope = Envelope( to="soef", sender=crypto.address, protocol_id=ProtocolId.from_str("fetchai/oef_search:0.1.0"), message=message_b, ) logger.info( "Searching for agents in radius={} of service={} at location=({},{})" .format( radius, service_name, service_location.latitude, service_location.longitude, )) multiplexer.put(envelope) time.sleep(4.0) # check for search results envelope = multiplexer.get() message = OefSearchSerializer().decode(envelope.message) assert len(message.agents) >= 0 finally: # Shut down the multiplexer multiplexer.disconnect() t.join()
class SigningMessage(Message): """A protocol for communication between skills and decision maker.""" protocol_id = ProtocolId.from_str("fetchai/signing:0.2.0") ErrorCode = CustomErrorCode RawMessage = CustomRawMessage RawTransaction = CustomRawTransaction SignedMessage = CustomSignedMessage SignedTransaction = CustomSignedTransaction Terms = CustomTerms class Performative(Enum): """Performatives for the signing protocol.""" ERROR = "error" SIGN_MESSAGE = "sign_message" SIGN_TRANSACTION = "sign_transaction" SIGNED_MESSAGE = "signed_message" SIGNED_TRANSACTION = "signed_transaction" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of SigningMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=SigningMessage.Performative(performative), **kwargs, ) self._performatives = { "error", "sign_message", "sign_transaction", "signed_message", "signed_transaction", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(SigningMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def error_code(self) -> CustomErrorCode: """Get the 'error_code' content from the message.""" assert self.is_set("error_code"), "'error_code' content is not set." return cast(CustomErrorCode, self.get("error_code")) @property def raw_message(self) -> CustomRawMessage: """Get the 'raw_message' content from the message.""" assert self.is_set("raw_message"), "'raw_message' content is not set." return cast(CustomRawMessage, self.get("raw_message")) @property def raw_transaction(self) -> CustomRawTransaction: """Get the 'raw_transaction' content from the message.""" assert self.is_set( "raw_transaction"), "'raw_transaction' content is not set." return cast(CustomRawTransaction, self.get("raw_transaction")) @property def signed_message(self) -> CustomSignedMessage: """Get the 'signed_message' content from the message.""" assert self.is_set( "signed_message"), "'signed_message' content is not set." return cast(CustomSignedMessage, self.get("signed_message")) @property def signed_transaction(self) -> CustomSignedTransaction: """Get the 'signed_transaction' content from the message.""" assert self.is_set( "signed_transaction"), "'signed_transaction' content is not set." return cast(CustomSignedTransaction, self.get("signed_transaction")) @property def skill_callback_ids(self) -> Tuple[str, ...]: """Get the 'skill_callback_ids' content from the message.""" assert self.is_set( "skill_callback_ids"), "'skill_callback_ids' content is not set." return cast(Tuple[str, ...], self.get("skill_callback_ids")) @property def skill_callback_info(self) -> Dict[str, str]: """Get the 'skill_callback_info' content from the message.""" assert self.is_set( "skill_callback_info"), "'skill_callback_info' content is not set." return cast(Dict[str, str], self.get("skill_callback_info")) @property def terms(self) -> CustomTerms: """Get the 'terms' content from the message.""" assert self.is_set("terms"), "'terms' content is not set." return cast(CustomTerms, self.get("terms")) def _is_consistent(self) -> bool: """Check that the message follows the signing protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == SigningMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == SigningMessage.Performative.SIGN_TRANSACTION: expected_nb_of_contents = 4 assert ( type(self.skill_callback_ids) == tuple ), "Invalid type for content 'skill_callback_ids'. Expected 'tuple'. Found '{}'.".format( type(self.skill_callback_ids)) assert all( type(element) == str for element in self.skill_callback_ids ), "Invalid type for tuple elements in content 'skill_callback_ids'. Expected 'str'." assert ( type(self.skill_callback_info) == dict ), "Invalid type for content 'skill_callback_info'. Expected 'dict'. Found '{}'.".format( type(self.skill_callback_info)) for ( key_of_skill_callback_info, value_of_skill_callback_info, ) in self.skill_callback_info.items(): assert ( type(key_of_skill_callback_info) == str ), "Invalid type for dictionary keys in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(key_of_skill_callback_info)) assert ( type(value_of_skill_callback_info) == str ), "Invalid type for dictionary values in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(value_of_skill_callback_info)) assert ( type(self.terms) == CustomTerms ), "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( type(self.terms)) assert ( type(self.raw_transaction) == CustomRawTransaction ), "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( type(self.raw_transaction)) elif self.performative == SigningMessage.Performative.SIGN_MESSAGE: expected_nb_of_contents = 4 assert ( type(self.skill_callback_ids) == tuple ), "Invalid type for content 'skill_callback_ids'. Expected 'tuple'. Found '{}'.".format( type(self.skill_callback_ids)) assert all( type(element) == str for element in self.skill_callback_ids ), "Invalid type for tuple elements in content 'skill_callback_ids'. Expected 'str'." assert ( type(self.skill_callback_info) == dict ), "Invalid type for content 'skill_callback_info'. Expected 'dict'. Found '{}'.".format( type(self.skill_callback_info)) for ( key_of_skill_callback_info, value_of_skill_callback_info, ) in self.skill_callback_info.items(): assert ( type(key_of_skill_callback_info) == str ), "Invalid type for dictionary keys in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(key_of_skill_callback_info)) assert ( type(value_of_skill_callback_info) == str ), "Invalid type for dictionary values in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(value_of_skill_callback_info)) assert ( type(self.terms) == CustomTerms ), "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( type(self.terms)) assert ( type(self.raw_message) == CustomRawMessage ), "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( type(self.raw_message)) elif self.performative == SigningMessage.Performative.SIGNED_TRANSACTION: expected_nb_of_contents = 3 assert ( type(self.skill_callback_ids) == tuple ), "Invalid type for content 'skill_callback_ids'. Expected 'tuple'. Found '{}'.".format( type(self.skill_callback_ids)) assert all( type(element) == str for element in self.skill_callback_ids ), "Invalid type for tuple elements in content 'skill_callback_ids'. Expected 'str'." assert ( type(self.skill_callback_info) == dict ), "Invalid type for content 'skill_callback_info'. Expected 'dict'. Found '{}'.".format( type(self.skill_callback_info)) for ( key_of_skill_callback_info, value_of_skill_callback_info, ) in self.skill_callback_info.items(): assert ( type(key_of_skill_callback_info) == str ), "Invalid type for dictionary keys in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(key_of_skill_callback_info)) assert ( type(value_of_skill_callback_info) == str ), "Invalid type for dictionary values in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(value_of_skill_callback_info)) assert ( type(self.signed_transaction) == CustomSignedTransaction ), "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( type(self.signed_transaction)) elif self.performative == SigningMessage.Performative.SIGNED_MESSAGE: expected_nb_of_contents = 3 assert ( type(self.skill_callback_ids) == tuple ), "Invalid type for content 'skill_callback_ids'. Expected 'tuple'. Found '{}'.".format( type(self.skill_callback_ids)) assert all( type(element) == str for element in self.skill_callback_ids ), "Invalid type for tuple elements in content 'skill_callback_ids'. Expected 'str'." assert ( type(self.skill_callback_info) == dict ), "Invalid type for content 'skill_callback_info'. Expected 'dict'. Found '{}'.".format( type(self.skill_callback_info)) for ( key_of_skill_callback_info, value_of_skill_callback_info, ) in self.skill_callback_info.items(): assert ( type(key_of_skill_callback_info) == str ), "Invalid type for dictionary keys in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(key_of_skill_callback_info)) assert ( type(value_of_skill_callback_info) == str ), "Invalid type for dictionary values in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(value_of_skill_callback_info)) assert ( type(self.signed_message) == CustomSignedMessage ), "Invalid type for content 'signed_message'. Expected 'SignedMessage'. Found '{}'.".format( type(self.signed_message)) elif self.performative == SigningMessage.Performative.ERROR: expected_nb_of_contents = 3 assert ( type(self.skill_callback_ids) == tuple ), "Invalid type for content 'skill_callback_ids'. Expected 'tuple'. Found '{}'.".format( type(self.skill_callback_ids)) assert all( type(element) == str for element in self.skill_callback_ids ), "Invalid type for tuple elements in content 'skill_callback_ids'. Expected 'str'." assert ( type(self.skill_callback_info) == dict ), "Invalid type for content 'skill_callback_info'. Expected 'dict'. Found '{}'.".format( type(self.skill_callback_info)) for ( key_of_skill_callback_info, value_of_skill_callback_info, ) in self.skill_callback_info.items(): assert ( type(key_of_skill_callback_info) == str ), "Invalid type for dictionary keys in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(key_of_skill_callback_info)) assert ( type(value_of_skill_callback_info) == str ), "Invalid type for dictionary values in content 'skill_callback_info'. Expected 'str'. Found '{}'.".format( type(value_of_skill_callback_info)) assert ( type(self.error_code) == CustomErrorCode ), "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( type(self.error_code)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class FipaMessage(Message): """A protocol for FIPA ACL.""" protocol_id = ProtocolId.from_str("fetchai/fipa:0.5.0") Description = CustomDescription Query = CustomQuery class Performative(Enum): """Performatives for the fipa protocol.""" ACCEPT = "accept" ACCEPT_W_INFORM = "accept_w_inform" CFP = "cfp" DECLINE = "decline" INFORM = "inform" MATCH_ACCEPT = "match_accept" MATCH_ACCEPT_W_INFORM = "match_accept_w_inform" PROPOSE = "propose" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of FipaMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=FipaMessage.Performative(performative), **kwargs, ) self._performatives = { "accept", "accept_w_inform", "cfp", "decline", "inform", "match_accept", "match_accept_w_inform", "propose", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(FipaMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def info(self) -> Dict[str, str]: """Get the 'info' content from the message.""" assert self.is_set("info"), "'info' content is not set." return cast(Dict[str, str], self.get("info")) @property def proposal(self) -> CustomDescription: """Get the 'proposal' content from the message.""" assert self.is_set("proposal"), "'proposal' content is not set." return cast(CustomDescription, self.get("proposal")) @property def query(self) -> CustomQuery: """Get the 'query' content from the message.""" assert self.is_set("query"), "'query' content is not set." return cast(CustomQuery, self.get("query")) def _is_consistent(self) -> bool: """Check that the message follows the fipa protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == FipaMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == FipaMessage.Performative.CFP: expected_nb_of_contents = 1 assert ( type(self.query) == CustomQuery ), "Invalid type for content 'query'. Expected 'Query'. Found '{}'.".format( type(self.query)) elif self.performative == FipaMessage.Performative.PROPOSE: expected_nb_of_contents = 1 assert ( type(self.proposal) == CustomDescription ), "Invalid type for content 'proposal'. Expected 'Description'. Found '{}'.".format( type(self.proposal)) elif self.performative == FipaMessage.Performative.ACCEPT_W_INFORM: expected_nb_of_contents = 1 assert ( type(self.info) == dict ), "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(self.info)) for key_of_info, value_of_info in self.info.items(): assert ( type(key_of_info) == str ), "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info)) assert ( type(value_of_info) == str ), "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info)) elif self.performative == FipaMessage.Performative.MATCH_ACCEPT_W_INFORM: expected_nb_of_contents = 1 assert ( type(self.info) == dict ), "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(self.info)) for key_of_info, value_of_info in self.info.items(): assert ( type(key_of_info) == str ), "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info)) assert ( type(value_of_info) == str ), "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info)) elif self.performative == FipaMessage.Performative.INFORM: expected_nb_of_contents = 1 assert ( type(self.info) == dict ), "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(self.info)) for key_of_info, value_of_info in self.info.items(): assert ( type(key_of_info) == str ), "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info)) assert ( type(value_of_info) == str ), "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info)) elif self.performative == FipaMessage.Performative.ACCEPT: expected_nb_of_contents = 0 elif self.performative == FipaMessage.Performative.DECLINE: expected_nb_of_contents = 0 elif self.performative == FipaMessage.Performative.MATCH_ACCEPT: expected_nb_of_contents = 0 # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class HttpMessage(Message): """A protocol for HTTP requests and responses.""" protocol_id = ProtocolId.from_str("fetchai/http:0.4.0") class Performative(Enum): """Performatives for the http protocol.""" REQUEST = "request" RESPONSE = "response" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of HttpMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=HttpMessage.Performative(performative), **kwargs, ) self._performatives = {"request", "response"} @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(HttpMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def bodyy(self) -> bytes: """Get the 'bodyy' content from the message.""" assert self.is_set("bodyy"), "'bodyy' content is not set." return cast(bytes, self.get("bodyy")) @property def headers(self) -> str: """Get the 'headers' content from the message.""" assert self.is_set("headers"), "'headers' content is not set." return cast(str, self.get("headers")) @property def method(self) -> str: """Get the 'method' content from the message.""" assert self.is_set("method"), "'method' content is not set." return cast(str, self.get("method")) @property def status_code(self) -> int: """Get the 'status_code' content from the message.""" assert self.is_set("status_code"), "'status_code' content is not set." return cast(int, self.get("status_code")) @property def status_text(self) -> str: """Get the 'status_text' content from the message.""" assert self.is_set("status_text"), "'status_text' content is not set." return cast(str, self.get("status_text")) @property def url(self) -> str: """Get the 'url' content from the message.""" assert self.is_set("url"), "'url' content is not set." return cast(str, self.get("url")) @property def version(self) -> str: """Get the 'version' content from the message.""" assert self.is_set("version"), "'version' content is not set." return cast(str, self.get("version")) def _is_consistent(self) -> bool: """Check that the message follows the http protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == HttpMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == HttpMessage.Performative.REQUEST: expected_nb_of_contents = 5 assert ( type(self.method) == str ), "Invalid type for content 'method'. Expected 'str'. Found '{}'.".format( type(self.method)) assert ( type(self.url) == str ), "Invalid type for content 'url'. Expected 'str'. Found '{}'.".format( type(self.url)) assert ( type(self.version) == str ), "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( type(self.version)) assert ( type(self.headers) == str ), "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( type(self.headers)) assert ( type(self.bodyy) == bytes ), "Invalid type for content 'bodyy'. Expected 'bytes'. Found '{}'.".format( type(self.bodyy)) elif self.performative == HttpMessage.Performative.RESPONSE: expected_nb_of_contents = 5 assert ( type(self.version) == str ), "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( type(self.version)) assert ( type(self.status_code) == int ), "Invalid type for content 'status_code'. Expected 'int'. Found '{}'.".format( type(self.status_code)) assert ( type(self.status_text) == str ), "Invalid type for content 'status_text'. Expected 'str'. Found '{}'.".format( type(self.status_text)) assert ( type(self.headers) == str ), "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( type(self.headers)) assert ( type(self.bodyy) == bytes ), "Invalid type for content 'bodyy'. Expected 'bytes'. Found '{}'.".format( type(self.bodyy)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class LedgerApiMessage(Message): """A protocol for ledger APIs requests and responses.""" protocol_id = ProtocolId.from_str("fetchai/ledger_api:0.2.0") RawTransaction = CustomRawTransaction SignedTransaction = CustomSignedTransaction Terms = CustomTerms TransactionDigest = CustomTransactionDigest TransactionReceipt = CustomTransactionReceipt class Performative(Enum): """Performatives for the ledger_api protocol.""" BALANCE = "balance" ERROR = "error" GET_BALANCE = "get_balance" GET_RAW_TRANSACTION = "get_raw_transaction" GET_TRANSACTION_RECEIPT = "get_transaction_receipt" RAW_TRANSACTION = "raw_transaction" SEND_SIGNED_TRANSACTION = "send_signed_transaction" TRANSACTION_DIGEST = "transaction_digest" TRANSACTION_RECEIPT = "transaction_receipt" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of LedgerApiMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=LedgerApiMessage.Performative(performative), **kwargs, ) self._performatives = { "balance", "error", "get_balance", "get_raw_transaction", "get_transaction_receipt", "raw_transaction", "send_signed_transaction", "transaction_digest", "transaction_receipt", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set("dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(LedgerApiMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def address(self) -> str: """Get the 'address' content from the message.""" assert self.is_set("address"), "'address' content is not set." return cast(str, self.get("address")) @property def balance(self) -> int: """Get the 'balance' content from the message.""" assert self.is_set("balance"), "'balance' content is not set." return cast(int, self.get("balance")) @property def code(self) -> int: """Get the 'code' content from the message.""" assert self.is_set("code"), "'code' content is not set." return cast(int, self.get("code")) @property def data(self) -> Optional[bytes]: """Get the 'data' content from the message.""" return cast(Optional[bytes], self.get("data")) @property def ledger_id(self) -> str: """Get the 'ledger_id' content from the message.""" assert self.is_set("ledger_id"), "'ledger_id' content is not set." return cast(str, self.get("ledger_id")) @property def message(self) -> Optional[str]: """Get the 'message' content from the message.""" return cast(Optional[str], self.get("message")) @property def raw_transaction(self) -> CustomRawTransaction: """Get the 'raw_transaction' content from the message.""" assert self.is_set("raw_transaction"), "'raw_transaction' content is not set." return cast(CustomRawTransaction, self.get("raw_transaction")) @property def signed_transaction(self) -> CustomSignedTransaction: """Get the 'signed_transaction' content from the message.""" assert self.is_set( "signed_transaction" ), "'signed_transaction' content is not set." return cast(CustomSignedTransaction, self.get("signed_transaction")) @property def terms(self) -> CustomTerms: """Get the 'terms' content from the message.""" assert self.is_set("terms"), "'terms' content is not set." return cast(CustomTerms, self.get("terms")) @property def transaction_digest(self) -> CustomTransactionDigest: """Get the 'transaction_digest' content from the message.""" assert self.is_set( "transaction_digest" ), "'transaction_digest' content is not set." return cast(CustomTransactionDigest, self.get("transaction_digest")) @property def transaction_receipt(self) -> CustomTransactionReceipt: """Get the 'transaction_receipt' content from the message.""" assert self.is_set( "transaction_receipt" ), "'transaction_receipt' content is not set." return cast(CustomTransactionReceipt, self.get("transaction_receipt")) def _is_consistent(self) -> bool: """Check that the message follows the ledger_api protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference) ) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0]) ) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1]) ) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id) ) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target) ) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == LedgerApiMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative ) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == LedgerApiMessage.Performative.GET_BALANCE: expected_nb_of_contents = 2 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.address) == str ), "Invalid type for content 'address'. Expected 'str'. Found '{}'.".format( type(self.address) ) elif self.performative == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: expected_nb_of_contents = 1 assert ( type(self.terms) == CustomTerms ), "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( type(self.terms) ) elif ( self.performative == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION ): expected_nb_of_contents = 1 assert ( type(self.signed_transaction) == CustomSignedTransaction ), "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( type(self.signed_transaction) ) elif ( self.performative == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT ): expected_nb_of_contents = 1 assert ( type(self.transaction_digest) == CustomTransactionDigest ), "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( type(self.transaction_digest) ) elif self.performative == LedgerApiMessage.Performative.BALANCE: expected_nb_of_contents = 2 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.balance) == int ), "Invalid type for content 'balance'. Expected 'int'. Found '{}'.".format( type(self.balance) ) elif self.performative == LedgerApiMessage.Performative.RAW_TRANSACTION: expected_nb_of_contents = 1 assert ( type(self.raw_transaction) == CustomRawTransaction ), "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( type(self.raw_transaction) ) elif self.performative == LedgerApiMessage.Performative.TRANSACTION_DIGEST: expected_nb_of_contents = 1 assert ( type(self.transaction_digest) == CustomTransactionDigest ), "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( type(self.transaction_digest) ) elif self.performative == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: expected_nb_of_contents = 1 assert ( type(self.transaction_receipt) == CustomTransactionReceipt ), "Invalid type for content 'transaction_receipt'. Expected 'TransactionReceipt'. Found '{}'.".format( type(self.transaction_receipt) ) elif self.performative == LedgerApiMessage.Performative.ERROR: expected_nb_of_contents = 1 assert ( type(self.code) == int ), "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( type(self.code) ) if self.is_set("message"): expected_nb_of_contents += 1 message = cast(str, self.message) assert ( type(message) == str ), "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( type(message) ) if self.is_set("data"): expected_nb_of_contents += 1 data = cast(bytes, self.data) assert ( type(data) == bytes ), "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( type(data) ) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents ) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target ) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class StateUpdateMessage(Message): """A protocol for state updates to the decision maker state.""" protocol_id = ProtocolId.from_str("fetchai/state_update:0.2.0") class Performative(Enum): """Performatives for the state_update protocol.""" APPLY = "apply" INITIALIZE = "initialize" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of StateUpdateMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=StateUpdateMessage.Performative(performative), **kwargs, ) self._performatives = {"apply", "initialize"} @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(StateUpdateMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def amount_by_currency_id(self) -> Dict[str, int]: """Get the 'amount_by_currency_id' content from the message.""" assert self.is_set("amount_by_currency_id" ), "'amount_by_currency_id' content is not set." return cast(Dict[str, int], self.get("amount_by_currency_id")) @property def exchange_params_by_currency_id(self) -> Dict[str, float]: """Get the 'exchange_params_by_currency_id' content from the message.""" assert self.is_set( "exchange_params_by_currency_id" ), "'exchange_params_by_currency_id' content is not set." return cast(Dict[str, float], self.get("exchange_params_by_currency_id")) @property def quantities_by_good_id(self) -> Dict[str, int]: """Get the 'quantities_by_good_id' content from the message.""" assert self.is_set("quantities_by_good_id" ), "'quantities_by_good_id' content is not set." return cast(Dict[str, int], self.get("quantities_by_good_id")) @property def utility_params_by_good_id(self) -> Dict[str, float]: """Get the 'utility_params_by_good_id' content from the message.""" assert self.is_set("utility_params_by_good_id" ), "'utility_params_by_good_id' content is not set." return cast(Dict[str, float], self.get("utility_params_by_good_id")) def _is_consistent(self) -> bool: """Check that the message follows the state_update protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == StateUpdateMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == StateUpdateMessage.Performative.INITIALIZE: expected_nb_of_contents = 4 assert ( type(self.exchange_params_by_currency_id) == dict ), "Invalid type for content 'exchange_params_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.exchange_params_by_currency_id)) for ( key_of_exchange_params_by_currency_id, value_of_exchange_params_by_currency_id, ) in self.exchange_params_by_currency_id.items(): assert ( type(key_of_exchange_params_by_currency_id) == str ), "Invalid type for dictionary keys in content 'exchange_params_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_exchange_params_by_currency_id)) assert ( type(value_of_exchange_params_by_currency_id) == float ), "Invalid type for dictionary values in content 'exchange_params_by_currency_id'. Expected 'float'. Found '{}'.".format( type(value_of_exchange_params_by_currency_id)) assert ( type(self.utility_params_by_good_id) == dict ), "Invalid type for content 'utility_params_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.utility_params_by_good_id)) for ( key_of_utility_params_by_good_id, value_of_utility_params_by_good_id, ) in self.utility_params_by_good_id.items(): assert ( type(key_of_utility_params_by_good_id) == str ), "Invalid type for dictionary keys in content 'utility_params_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_utility_params_by_good_id)) assert ( type(value_of_utility_params_by_good_id) == float ), "Invalid type for dictionary values in content 'utility_params_by_good_id'. Expected 'float'. Found '{}'.".format( type(value_of_utility_params_by_good_id)) assert ( type(self.amount_by_currency_id) == dict ), "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id)) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): assert ( type(key_of_amount_by_currency_id) == str ), "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id)) assert ( type(value_of_amount_by_currency_id) == int ), "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id)) assert ( type(self.quantities_by_good_id) == dict ), "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id)) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): assert ( type(key_of_quantities_by_good_id) == str ), "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id)) assert ( type(value_of_quantities_by_good_id) == int ), "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id)) elif self.performative == StateUpdateMessage.Performative.APPLY: expected_nb_of_contents = 2 assert ( type(self.amount_by_currency_id) == dict ), "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id)) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): assert ( type(key_of_amount_by_currency_id) == str ), "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id)) assert ( type(value_of_amount_by_currency_id) == int ), "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id)) assert ( type(self.quantities_by_good_id) == dict ), "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id)) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): assert ( type(key_of_quantities_by_good_id) == str ), "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id)) assert ( type(value_of_quantities_by_good_id) == int ), "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class DefaultMessage(Message): """A protocol for exchanging any bytes message.""" protocol_id = ProtocolId.from_str("fetchai/default:0.4.0") ErrorCode = CustomErrorCode class Performative(Enum): """Performatives for the default protocol.""" BYTES = "bytes" ERROR = "error" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of DefaultMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=DefaultMessage.Performative(performative), **kwargs, ) self._performatives = {"bytes", "error"} @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(DefaultMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def content(self) -> bytes: """Get the 'content' content from the message.""" assert self.is_set("content"), "'content' content is not set." return cast(bytes, self.get("content")) @property def error_code(self) -> CustomErrorCode: """Get the 'error_code' content from the message.""" assert self.is_set("error_code"), "'error_code' content is not set." return cast(CustomErrorCode, self.get("error_code")) @property def error_data(self) -> Dict[str, bytes]: """Get the 'error_data' content from the message.""" assert self.is_set("error_data"), "'error_data' content is not set." return cast(Dict[str, bytes], self.get("error_data")) @property def error_msg(self) -> str: """Get the 'error_msg' content from the message.""" assert self.is_set("error_msg"), "'error_msg' content is not set." return cast(str, self.get("error_msg")) def _is_consistent(self) -> bool: """Check that the message follows the default protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == DefaultMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == DefaultMessage.Performative.BYTES: expected_nb_of_contents = 1 assert ( type(self.content) == bytes ), "Invalid type for content 'content'. Expected 'bytes'. Found '{}'.".format( type(self.content)) elif self.performative == DefaultMessage.Performative.ERROR: expected_nb_of_contents = 3 assert ( type(self.error_code) == CustomErrorCode ), "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( type(self.error_code)) assert ( type(self.error_msg) == str ), "Invalid type for content 'error_msg'. Expected 'str'. Found '{}'.".format( type(self.error_msg)) assert ( type(self.error_data) == dict ), "Invalid type for content 'error_data'. Expected 'dict'. Found '{}'.".format( type(self.error_data)) for key_of_error_data, value_of_error_data in self.error_data.items( ): assert ( type(key_of_error_data) == str ), "Invalid type for dictionary keys in content 'error_data'. Expected 'str'. Found '{}'.".format( type(key_of_error_data)) assert ( type(value_of_error_data) == bytes ), "Invalid type for dictionary values in content 'error_data'. Expected 'bytes'. Found '{}'.".format( type(value_of_error_data)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class ContractApiMessage(Message): """A protocol for contract APIs requests and responses.""" protocol_id = ProtocolId.from_str("fetchai/contract_api:0.2.0") Kwargs = CustomKwargs RawMessage = CustomRawMessage RawTransaction = CustomRawTransaction State = CustomState class Performative(Enum): """Performatives for the contract_api protocol.""" ERROR = "error" GET_DEPLOY_TRANSACTION = "get_deploy_transaction" GET_RAW_MESSAGE = "get_raw_message" GET_RAW_TRANSACTION = "get_raw_transaction" GET_STATE = "get_state" RAW_MESSAGE = "raw_message" RAW_TRANSACTION = "raw_transaction" STATE = "state" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of ContractApiMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=ContractApiMessage.Performative(performative), **kwargs, ) self._performatives = { "error", "get_deploy_transaction", "get_raw_message", "get_raw_transaction", "get_state", "raw_message", "raw_transaction", "state", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set("dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(ContractApiMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def callable(self) -> str: """Get the 'callable' content from the message.""" assert self.is_set("callable"), "'callable' content is not set." return cast(str, self.get("callable")) @property def code(self) -> Optional[int]: """Get the 'code' content from the message.""" return cast(Optional[int], self.get("code")) @property def contract_address(self) -> str: """Get the 'contract_address' content from the message.""" assert self.is_set("contract_address"), "'contract_address' content is not set." return cast(str, self.get("contract_address")) @property def contract_id(self) -> str: """Get the 'contract_id' content from the message.""" assert self.is_set("contract_id"), "'contract_id' content is not set." return cast(str, self.get("contract_id")) @property def data(self) -> bytes: """Get the 'data' content from the message.""" assert self.is_set("data"), "'data' content is not set." return cast(bytes, self.get("data")) @property def kwargs(self) -> CustomKwargs: """Get the 'kwargs' content from the message.""" assert self.is_set("kwargs"), "'kwargs' content is not set." return cast(CustomKwargs, self.get("kwargs")) @property def ledger_id(self) -> str: """Get the 'ledger_id' content from the message.""" assert self.is_set("ledger_id"), "'ledger_id' content is not set." return cast(str, self.get("ledger_id")) @property def message(self) -> Optional[str]: """Get the 'message' content from the message.""" return cast(Optional[str], self.get("message")) @property def raw_message(self) -> CustomRawMessage: """Get the 'raw_message' content from the message.""" assert self.is_set("raw_message"), "'raw_message' content is not set." return cast(CustomRawMessage, self.get("raw_message")) @property def raw_transaction(self) -> CustomRawTransaction: """Get the 'raw_transaction' content from the message.""" assert self.is_set("raw_transaction"), "'raw_transaction' content is not set." return cast(CustomRawTransaction, self.get("raw_transaction")) @property def state(self) -> CustomState: """Get the 'state' content from the message.""" assert self.is_set("state"), "'state' content is not set." return cast(CustomState, self.get("state")) def _is_consistent(self) -> bool: """Check that the message follows the contract_api protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference) ) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0]) ) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1]) ) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id) ) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target) ) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == ContractApiMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative ) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if ( self.performative == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION ): expected_nb_of_contents = 4 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.contract_id) == str ), "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( type(self.contract_id) ) assert ( type(self.callable) == str ), "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( type(self.callable) ) assert ( type(self.kwargs) == CustomKwargs ), "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( type(self.kwargs) ) elif ( self.performative == ContractApiMessage.Performative.GET_RAW_TRANSACTION ): expected_nb_of_contents = 5 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.contract_id) == str ), "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( type(self.contract_id) ) assert ( type(self.contract_address) == str ), "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( type(self.contract_address) ) assert ( type(self.callable) == str ), "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( type(self.callable) ) assert ( type(self.kwargs) == CustomKwargs ), "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( type(self.kwargs) ) elif self.performative == ContractApiMessage.Performative.GET_RAW_MESSAGE: expected_nb_of_contents = 5 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.contract_id) == str ), "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( type(self.contract_id) ) assert ( type(self.contract_address) == str ), "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( type(self.contract_address) ) assert ( type(self.callable) == str ), "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( type(self.callable) ) assert ( type(self.kwargs) == CustomKwargs ), "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( type(self.kwargs) ) elif self.performative == ContractApiMessage.Performative.GET_STATE: expected_nb_of_contents = 5 assert ( type(self.ledger_id) == str ), "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ) assert ( type(self.contract_id) == str ), "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( type(self.contract_id) ) assert ( type(self.contract_address) == str ), "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( type(self.contract_address) ) assert ( type(self.callable) == str ), "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( type(self.callable) ) assert ( type(self.kwargs) == CustomKwargs ), "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( type(self.kwargs) ) elif self.performative == ContractApiMessage.Performative.STATE: expected_nb_of_contents = 1 assert ( type(self.state) == CustomState ), "Invalid type for content 'state'. Expected 'State'. Found '{}'.".format( type(self.state) ) elif self.performative == ContractApiMessage.Performative.RAW_TRANSACTION: expected_nb_of_contents = 1 assert ( type(self.raw_transaction) == CustomRawTransaction ), "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( type(self.raw_transaction) ) elif self.performative == ContractApiMessage.Performative.RAW_MESSAGE: expected_nb_of_contents = 1 assert ( type(self.raw_message) == CustomRawMessage ), "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( type(self.raw_message) ) elif self.performative == ContractApiMessage.Performative.ERROR: expected_nb_of_contents = 1 if self.is_set("code"): expected_nb_of_contents += 1 code = cast(int, self.code) assert ( type(code) == int ), "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( type(code) ) if self.is_set("message"): expected_nb_of_contents += 1 message = cast(str, self.message) assert ( type(message) == str ), "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( type(message) ) assert ( type(self.data) == bytes ), "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( type(self.data) ) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents ) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target ) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True
class OefSearchMessage(Message): """A protocol for interacting with an OEF search service.""" protocol_id = ProtocolId.from_str("fetchai/oef_search:0.4.0") Description = CustomDescription OefErrorOperation = CustomOefErrorOperation Query = CustomQuery class Performative(Enum): """Performatives for the oef_search protocol.""" OEF_ERROR = "oef_error" REGISTER_SERVICE = "register_service" SEARCH_RESULT = "search_result" SEARCH_SERVICES = "search_services" UNREGISTER_SERVICE = "unregister_service" def __str__(self): """Get the string representation.""" return str(self.value) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of OefSearchMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=OefSearchMessage.Performative(performative), **kwargs, ) self._performatives = { "oef_error", "register_service", "search_result", "search_services", "unregister_service", } @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" assert self.is_set( "dialogue_reference"), "dialogue_reference is not set." return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" assert self.is_set("message_id"), "message_id is not set." return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" assert self.is_set("performative"), "performative is not set." return cast(OefSearchMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" assert self.is_set("target"), "target is not set." return cast(int, self.get("target")) @property def agents(self) -> Tuple[str, ...]: """Get the 'agents' content from the message.""" assert self.is_set("agents"), "'agents' content is not set." return cast(Tuple[str, ...], self.get("agents")) @property def oef_error_operation(self) -> CustomOefErrorOperation: """Get the 'oef_error_operation' content from the message.""" assert self.is_set( "oef_error_operation"), "'oef_error_operation' content is not set." return cast(CustomOefErrorOperation, self.get("oef_error_operation")) @property def query(self) -> CustomQuery: """Get the 'query' content from the message.""" assert self.is_set("query"), "'query' content is not set." return cast(CustomQuery, self.get("query")) @property def service_description(self) -> CustomDescription: """Get the 'service_description' content from the message.""" assert self.is_set( "service_description"), "'service_description' content is not set." return cast(CustomDescription, self.get("service_description")) def _is_consistent(self) -> bool: """Check that the message follows the oef_search protocol.""" try: assert ( type(self.dialogue_reference) == tuple ), "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference)) assert ( type(self.dialogue_reference[0]) == str ), "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0])) assert ( type(self.dialogue_reference[1]) == str ), "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1])) assert ( type(self.message_id) == int ), "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id)) assert ( type(self.target) == int ), "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target)) # Light Protocol Rule 2 # Check correct performative assert ( type(self.performative) == OefSearchMessage.Performative ), "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative) # Check correct contents actual_nb_of_contents = len(self.body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == OefSearchMessage.Performative.REGISTER_SERVICE: expected_nb_of_contents = 1 assert ( type(self.service_description) == CustomDescription ), "Invalid type for content 'service_description'. Expected 'Description'. Found '{}'.".format( type(self.service_description)) elif self.performative == OefSearchMessage.Performative.UNREGISTER_SERVICE: expected_nb_of_contents = 1 assert ( type(self.service_description) == CustomDescription ), "Invalid type for content 'service_description'. Expected 'Description'. Found '{}'.".format( type(self.service_description)) elif self.performative == OefSearchMessage.Performative.SEARCH_SERVICES: expected_nb_of_contents = 1 assert ( type(self.query) == CustomQuery ), "Invalid type for content 'query'. Expected 'Query'. Found '{}'.".format( type(self.query)) elif self.performative == OefSearchMessage.Performative.SEARCH_RESULT: expected_nb_of_contents = 1 assert ( type(self.agents) == tuple ), "Invalid type for content 'agents'. Expected 'tuple'. Found '{}'.".format( type(self.agents)) assert all( type(element) == str for element in self.agents ), "Invalid type for tuple elements in content 'agents'. Expected 'str'." elif self.performative == OefSearchMessage.Performative.OEF_ERROR: expected_nb_of_contents = 1 assert ( type(self.oef_error_operation) == CustomOefErrorOperation ), "Invalid type for content 'oef_error_operation'. Expected 'OefErrorOperation'. Found '{}'.".format( type(self.oef_error_operation)) # Check correct content count assert ( expected_nb_of_contents == actual_nb_of_contents ), "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents) # Light Protocol Rule 3 if self.message_id == 1: assert ( self.target == 0 ), "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target) else: assert ( 0 < self.target < self.message_id ), "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ) except (AssertionError, ValueError, KeyError) as e: logger.error(str(e)) return False return True