def validate_and_parse_message(data: Any, peer_address: Address) -> List[Message]: messages: List[Message] = list() if not isinstance(data, str): log.warning( "Received Message body not a string", message_data=data, peer_address=to_checksum_address(peer_address), ) return [] for line in data.splitlines(): line = line.strip() if not line: continue try: message = MessageSerializer.deserialize(line) except SerializationError as ex: log.warning( "Not a valid Message", message_data=line, peer_address=to_checksum_address(peer_address), _exc=ex, ) continue if not isinstance(message, SignedMessage): log.warning( "Message not a SignedMessage!", message=message, peer_address=to_checksum_address(peer_address), ) continue if message.sender != peer_address: log.warning( "Message not signed by sender!", message=message, signer=message.sender, peer_address=to_checksum_address(peer_address), ) continue messages.append(message) return messages
def deserialize_messages( data: str, peer_address: Address, rate_limiter: Optional[RateLimiter] = None) -> List[SignedMessage]: messages: List[SignedMessage] = list() if rate_limiter: rate_limiter.reset_if_it_is_time() # This size includes some bytes of overhead for python. But otherwise we # would have to either count characters for decode the whole string before # checking the rate limiting. size = sys.getsizeof(data) if not rate_limiter.check_and_count(peer_address, size): log.warning("Sender is rate limited", sender=peer_address) return [] for line in data.splitlines(): line = line.strip() if not line: continue logger = log.bind(peer_address=to_checksum_address(peer_address)) try: message = MessageSerializer.deserialize(line) except (SerializationError, ValidationError, KeyError, ValueError) as ex: logger.warning("Message data JSON is not a valid message", message_data=line, _exc=ex) continue if not isinstance(message, SignedMessage): logger.warning("Received invalid message", message=message) continue if message.sender != peer_address: logger.warning("Message not signed by sender!", message=message, signer=message.sender) continue messages.append(message) return messages
def test_encoding_and_decoding(): message_factories = ( factories.LockedTransferProperties(), factories.RefundTransferProperties(), factories.LockExpiredProperties(), factories.UnlockProperties(), ) messages = [factories.create(factory) for factory in message_factories] # TODO Handle these with factories once #5091 is implemented messages.append( Delivered( delivered_message_identifier=factories.make_message_identifier(), signature=factories.make_signature(), )) messages.append( Processed( message_identifier=factories.make_message_identifier(), signature=factories.make_signature(), )) messages.append( RevealSecret( message_identifier=factories.make_message_identifier(), secret=factories.make_secret(), signature=factories.make_signature(), )) messages.append( SecretRequest( message_identifier=factories.make_message_identifier(), payment_identifier=factories.make_payment_id(), secrethash=factories.make_secret_hash(), amount=factories.make_token_amount(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawRequest( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawConfirmation( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( WithdrawExpired( message_identifier=factories.make_message_identifier(), chain_id=factories.make_chain_id(), token_network_address=factories.make_token_network_address(), channel_identifier=factories.make_channel_identifier(), participant=factories.make_address(), total_withdraw=factories.make_token_amount(), nonce=factories.make_nonce(), expiration=factories.make_block_number(), signature=factories.make_signature(), )) messages.append( PFSCapacityUpdate( canonical_identifier=factories.make_canonical_identifier(), updating_participant=factories.make_address(), other_participant=factories.make_address(), updating_nonce=factories.make_nonce(), other_nonce=factories.make_nonce(), updating_capacity=factories.make_token_amount(), other_capacity=factories.make_token_amount(), reveal_timeout=factories.make_uint64(), signature=factories.make_signature(), )) messages.append( PFSFeeUpdate( canonical_identifier=factories.make_canonical_identifier(), updating_participant=factories.make_address(), fee_schedule=factories.create( factories.FeeScheduleStateProperties()), timestamp=datetime.now(), signature=factories.make_signature(), )) messages.append( RequestMonitoring( reward_amount=factories.make_token_amount(), balance_proof=SignedBlindedBalanceProof. from_balance_proof_signed_state( factories.create( factories.BalanceProofSignedStateProperties())), monitoring_service_contract_address=factories.make_address(), non_closing_participant=factories.make_address(), non_closing_signature=factories.make_signature(), signature=factories.make_signature(), )) for message in messages: serialized = MessageSerializer.serialize(message) deserialized = MessageSerializer.deserialize(serialized) assert deserialized == message
def test_bad_messages(): "SerializationErrors should be raised on all kinds of wrong messages" for message in ["{}", "[]", '"foo"', "123"]: with pytest.raises(SerializationError): MessageSerializer.deserialize(message)
def test_encoding_and_decoding(): for message in messages: serialized = MessageSerializer.serialize(message) deserialized = MessageSerializer.deserialize(serialized) assert deserialized == message