def test_receive_mediatedtransfer_outoforder(raiden_network, private_keys): alice_app = raiden_network[0] messages = setup_messages_cb() graph = alice_app.raiden.channelgraphs.values()[0] token_address = graph.token_address mt_helper = MediatedTransferTestHelper(raiden_network, graph) initiator_address = alice_app.raiden.address path = mt_helper.get_paths_of_length(initiator_address, 2) # make sure we have no messages before the transfer assert len(messages) == 0 alice_address, bob_address, charlie_address = path amount = 10 result = alice_app.raiden.transfer_async( token_address, amount, charlie_address, ) # check for invitation ping assert len(messages) == 2 # Ping, Ack ping_message = decode(messages[0]) assert isinstance(ping_message, Ping) decoded = decode(messages[1]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping_message.encode() + charlie_address) assert result.wait(timeout=10) gevent.sleep(1.) # check that transfer messages were added assert len(messages) == 22 # Ping, Ack + tranfer messages # make sure that the mediated transfer is sent after the invitation ping assert isinstance(decode(messages[2]), MediatedTransfer) # and now send one more mediated transfer with the same nonce, simulating # an out-of-order/resent message that arrives late locksroot = HASH lock = Lock(amount, 1, locksroot) identifier = create_default_identifier( alice_app.raiden.address, graph.token_address, charlie_address, ) mediated_transfer = MediatedTransfer(identifier=identifier, nonce=1, token=token_address, transferred_amount=amount, recipient=bob_address, locksroot=locksroot, lock=lock, target=charlie_address, initiator=initiator_address, fee=0) alice_key = PrivateKey(private_keys[0]) bob_app = mt_helper.get_app_from_address(bob_address) sign_and_send(mediated_transfer, alice_key, alice_address, bob_app)
def test_healthcheck_with_normal_peer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() asset_manager0 = app0.raiden.managers_by_asset_address.values()[0] asset_manager1 = app1.raiden.managers_by_asset_address.values()[0] max_unresponsive_time = app0.raiden.config['max_unresponsive_time'] assert asset_manager0.asset_address == asset_manager1.asset_address assert app1.raiden.address in asset_manager0.partneraddress_channel amount = 10 app0.raiden.api.transfer( asset_manager0.asset_address, amount, target=app1.raiden.address, ) gevent.sleep(max_unresponsive_time) assert asset_manager0.channelgraph.has_path( app0.raiden.address, app1.raiden.address ) # At this point we should have sent a direct transfer and got back the ack # and gotten at least 1 ping - ack for a normal healthcheck assert len(messages) >= 4 # DirectTransfer, Ack, Ping, Ack assert isinstance(decode(messages[0]), DirectTransfer) assert isinstance(decode(messages[1]), Ack) assert isinstance(decode(messages[2]), Ping) assert isinstance(decode(messages[3]), Ack)
def test_mediated_transfer(raiden_network): alice_app = raiden_network[0] messages = setup_messages_cb() graph = alice_app.raiden.channelgraphs.values()[0] token_address = graph.token_address mt_helper = MediatedTransferTestHelper(raiden_network, graph) initiator_address = alice_app.raiden.address path = mt_helper.get_paths_of_length(initiator_address, 2) mt_helper.assert_path_in_shortest_paths(path, initiator_address, 2) alice_address, bob_address, charlie_address = path # channels (alice <-> bob <-> charlie) channel_ab = mt_helper.get_channel(alice_address, bob_address) channel_ba = mt_helper.get_channel(bob_address, alice_address) channel_bc = mt_helper.get_channel(bob_address, charlie_address) channel_cb = mt_helper.get_channel(charlie_address, bob_address) initial_balance_ab = channel_ab.balance initial_balance_ba = channel_ba.balance initial_balance_bc = channel_bc.balance initial_balance_cb = channel_cb.balance amount = 10 result = alice_app.raiden.transfer_async( token_address, amount, charlie_address, ) # check for invitation ping assert len(messages) == 2 # Ping, Ack ping_message = decode(messages[0]) assert isinstance(ping_message, Ping) decoded = decode(messages[1]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping_message.encode() + charlie_address) assert channel_ab.locked == amount # Cannot assert the intermediary state of the channels since the code is # concurrently executed. # assert channel_ba.outstanding == amount # assert channel_bc.locked == amount # assert channel_cb.outstanding == amount assert result.wait(timeout=10) gevent.sleep(.1) # wait for the other nodes to sync # check that transfer messages were added assert len(messages) == 22 # Ping, Ack + tranfer messages # make sure that the mediated transfer is sent after the invitation ping assert isinstance(decode(messages[2]), MediatedTransfer) assert initial_balance_ab - amount == channel_ab.balance assert initial_balance_ba + amount == channel_ba.balance assert initial_balance_bc - amount == channel_bc.balance assert initial_balance_cb + amount == channel_cb.balance
def test_healthcheck_with_normal_peer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() graph0 = app0.raiden.channelgraphs.values()[0] graph1 = app1.raiden.channelgraphs.values()[0] max_unresponsive_time = app0.raiden.config['max_unresponsive_time'] assert graph0.token_address == graph1.token_address assert app1.raiden.address in graph0.partneraddress_channel amount = 10 target = app1.raiden.address result = app0.raiden.transfer_async( graph0.token_address, amount, target, ) assert result.wait(timeout=10) gevent.sleep(max_unresponsive_time) assert graph0.has_path( app0.raiden.address, app1.raiden.address ) # At this point we should have sent a direct transfer and got back the ack # and gotten at least 1 ping - ack for a normal healthcheck assert len(messages) >= 4 # DirectTransfer, Ack, Ping, Ack assert isinstance(decode(messages[0]), DirectTransfer) assert isinstance(decode(messages[1]), Ack) assert isinstance(decode(messages[2]), Ping) assert isinstance(decode(messages[3]), Ack)
def test_healthcheck_with_bad_peer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking UnreliableTransport.droprate = 10 # Let's allow some messages to go through UnreliableTransport.network.counter = 1 messages = setup_messages_cb() send_ping_time = app0.raiden.config['send_ping_time'] max_unresponsive_time = app0.raiden.config['max_unresponsive_time'] graph0 = app0.raiden.channelgraphs.values()[0] graph1 = app1.raiden.channelgraphs.values()[0] assert graph0.token_address == graph1.token_address assert app1.raiden.address in graph0.partneraddress_channel amount = 10 target = app1.raiden.address result = app0.raiden.transfer_async( graph0.token_address, amount, target, ) assert result.wait(timeout=10) gevent.sleep(2) assert graph0.has_path( app0.raiden.address, app1.raiden.address ) # At this point we should have sent a direct transfer and got back the ack assert len(messages) == 2 # DirectTransfer, Ack assert isinstance(decode(messages[0]), DirectTransfer) assert isinstance(decode(messages[1]), Ack) # now let's make things interesting and drop every message UnreliableTransport.droprate = 1 UnreliableTransport.network.counter = 0 gevent.sleep(send_ping_time) # At least 1 ping should have been sent by now but gotten no response assert len(messages) >= 3 for msg in messages[2:]: assert isinstance(decode(msg), Ping) gevent.sleep(max_unresponsive_time - send_ping_time) # By now our peer has not replied and must have been removed from the graph assert not graph0.has_path( app0.raiden.address, app1.raiden.address ) final_messages_num = len(messages) # Let's make sure no new pings are sent afterwards gevent.sleep(2) assert len(messages) == final_messages_num
def test_ping_udp(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send_and_wait(app1.raiden.address, ping) gevent.sleep(0.1) assert len(messages) == 2 # Ping, Ack assert decode(messages[0]) == ping decoded = decode(messages[1]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping.encode() + app1.raiden.address)
def test_healthcheck_with_bad_peer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking UnreliableTransport.droprate = 10 # Let's allow some messages to go through UnreliableTransport.network.counter = 1 messages = setup_messages_cb() send_ping_time = app0.raiden.config['send_ping_time'] max_unresponsive_time = app0.raiden.config['max_unresponsive_time'] asset_manager0 = app0.raiden.managers_by_asset_address.values()[0] asset_manager1 = app1.raiden.managers_by_asset_address.values()[0] assert asset_manager0.asset_address == asset_manager1.asset_address assert app1.raiden.address in asset_manager0.partneraddress_channel amount = 10 app0.raiden.api.transfer( asset_manager0.asset_address, amount, target=app1.raiden.address, ) gevent.sleep(2) assert asset_manager0.channelgraph.has_path( app0.raiden.address, app1.raiden.address ) # At this point we should have sent a direct transfer and got back the ack assert len(messages) == 2 # DirectTransfer, Ack assert isinstance(decode(messages[0]), DirectTransfer) assert isinstance(decode(messages[1]), Ack) # now let's make things interesting and drop every message UnreliableTransport.droprate = 1 UnreliableTransport.network.counter = 0 gevent.sleep(send_ping_time) # At least 1 ping should have been sent by now but gotten no response assert len(messages) >= 3 for msg in messages[2:]: assert isinstance(decode(msg), Ping) gevent.sleep(max_unresponsive_time - send_ping_time) # By now our peer has not replied and must have been removed from the graph assert not asset_manager0.channelgraph.has_path( app0.raiden.address, app1.raiden.address ) final_messages_num = len(messages) # Let's make sure no new pings are sent afterwards gevent.sleep(2) assert len(messages) == final_messages_num
def test_ping(): apps = create_network(num_nodes=2, num_assets=0, channels_per_node=0) a0, a1 = apps messages = setup_messages_cb() p = Ping(nonce=0) a0.raiden.sign(p) a0.raiden.protocol.send(a1.raiden.address, p) gevent.sleep(0.1) assert len(messages) == 2 # Ping, Ack assert decode(messages[0]) == p a = decode(messages[1]) assert isinstance(a, Ack) assert a.echo == p.hash
def test_ping(): apps = create_network(num_nodes=2, num_assets=0, channels_per_node=0) app0, app1 = apps # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send(app1.raiden.address, ping) gevent.sleep(0.1) assert len(messages) == 2 # Ping, Ack assert decode(messages[0]) == ping decoded = decode(messages[1]) assert isinstance(decoded, Ack) assert decoded.echo == ping.hash
def test_ping_unreachable(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking # drop everything to force disabling of re-sends app0.raiden.protocol.transport.droprate = 1 app1.raiden.protocol.transport.droprate = 1 app0.raiden.protocol.retry_interval = 0.1 # for fast tests messages = setup_messages_cb() ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() async_result = app0.raiden.protocol.send_raw_with_result( ping_encoded, app1.raiden.address, ) assert async_result.wait(2) is None, "The message was dropped, it can't be acknowledged" # Raiden node will start pinging as soon as a new channel # is established. We need to test if # a) there is our original message in the queue # b) there are only Ping message types in messages_decoded = [decode(m) for m in messages] assert ping_message in messages_decoded for message in messages_decoded: assert isinstance(message, Ping)
def receive(self, data): if len(data) > UDP_MAX_MESSAGE_SIZE: log.error('receive packet larger than maximum size', length=len(data)) return # Repeat the 'PROCESSED' message if the message has been handled before message_id = messageid_from_data(data, self.raiden.address) if message_id in self.messageids_to_processedmessages: self._maybe_send_processed( *self.messageids_to_processedmessages[message_id]) return message = decode(data) if isinstance(message, Processed): self.receive_processed(message) elif isinstance(message, Ping): self.receive_ping(message, message_id) elif isinstance(message, SignedMessage): self.receive_message(message, message_id) elif log.isEnabledFor(logging.ERROR): log.error( 'Invalid message', message=hexlify(data), )
def receive(self, messagedata): """ Handle an UDP packet. """ # pylint: disable=unidiomatic-typecheck if len(messagedata) > UDP_MAX_MESSAGE_SIZE: log.error( 'INVALID MESSAGE: Packet larger than maximum size', node=pex(self.raiden.address), message=hexlify(messagedata), length=len(messagedata), ) return message = decode(messagedata) if type(message) == Pong: self.receive_pong(message) elif type(message) == Ping: self.receive_ping(message) elif type(message) == Delivered: self.receive_delivered(message) elif message is not None: self.receive_message(message) elif log.isEnabledFor(logging.ERROR): log.error( 'INVALID MESSAGE: Unknown cmdid', node=pex(self.raiden.address), message=hexlify(messagedata), )
def receive(self, data): # ignore large packets if len(data) > self.max_message_size: log.error('receive packet larger than maximum size', length=len(data)) return msghash = sha3(data) # check if we handled this message already, if so repeat Ack if msghash in self.sent_acks: return self.send_ack(*self.sent_acks[msghash]) # We ignore the sending endpoint as this can not be known w/ UDP msg = messages.decode(data) if isinstance(msg, Ack): # we might receive the same Ack more than once if msg.echo in self.number_of_tries: log.debug('ACK RECEIVED {} [echo={}]'.format( pex(self.raiden.address), pex(msg.echo) )) del self.number_of_tries[msg.echo] else: log.debug('DUPLICATED ACK RECEIVED {} [echo={}]'.format( pex(self.raiden.address), pex(msg.echo) )) else: assert isinstance(msg, Secret) or msg.sender self.raiden.on_message(msg, msghash)
def test_hash(): ping = Ping(nonce=0, current_protocol_version=constants.PROTOCOL_VERSION) ping.sign(PRIVKEY) data = ping.encode() msghash = sha3(data) decoded_ping = decode(data) assert sha3(decoded_ping.encode()) == msghash
def test_hash(): ping = Ping(nonce=0) ping.sign(PRIVKEY) data = ping.encode() msghash = sha3(data) decoded_ping = decode(data) assert sha3(decoded_ping.encode()) == msghash
def test_healthcheck_with_normal_peer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() graph0 = app0.raiden.token_to_channelgraph.values()[0] graph1 = app1.raiden.token_to_channelgraph.values()[0] assert graph0.token_address == graph1.token_address assert app1.raiden.address in graph0.partneraddress_to_channel amount = 10 target = app1.raiden.address result = app0.raiden.direct_transfer_async( graph0.token_address, amount, target, identifier=1, ) assert result.wait(timeout=10) assert graph0.has_path( app0.raiden.address, app1.raiden.address ) # At this point we should have sent a direct transfer and got back the ack # and gotten at least 1 ping - ack for a normal healthcheck decoded_messages = [decode(m) for m in unique(messages)] direct_messages = get_messages_by_type(decoded_messages, DirectTransfer) assert len(direct_messages) == 1 assert_ack_for(app1, direct_messages[0], decoded_messages) ping_messages = get_messages_by_type(decoded_messages, Ping) assert ping_messages
def test_ping(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() async_result = app0.raiden.protocol.send_raw_with_result( ping_encoded, app1.raiden.address, ) assert async_result.wait(2), "The message was not acknowledged" expected_echohash = sha3(ping_encoded + app1.raiden.address) messages_decoded = [decode(m) for m in messages] ack_message = next( decoded for decoded in messages_decoded if isinstance(decoded, Ack) and decoded.echo == expected_echohash) # the ping message was sent and acknowledged assert ping_encoded in messages assert ack_message
def receive(self, data): if len(data) > UDP_MAX_MESSAGE_SIZE: log.error('receive packet larger than maximum size', length=len(data)) return # Repeat the ACK if the message has been handled before echohash = sha3(data + self.raiden.address) if echohash in self.receivedhashes_to_acks: self._maybe_send_ack(*self.receivedhashes_to_acks[echohash]) return message = decode(data) if isinstance(message, Ack): self.receive_ack(message) elif isinstance(message, Ping): self.receive_ping(message, echohash) elif isinstance(message, SignedMessage): self.receive_message(message, echohash) elif log.isEnabledFor(logging.ERROR): log.error( 'Invalid message', message=hexlify(data), )
def test_ping_unreachable(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking UnreliableTransport.droprate = 1 # drop everything to force disabling of re-sends app0.raiden.protocol.retry_interval = 0.1 # for fast tests messages = setup_messages_cb() UnreliableTransport.network.counter = 0 ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() async_result = app0.raiden.protocol.send_raw_with_result( ping_encoded, app1.raiden.address, ) assert async_result.wait( 2) is None, "The message was dropped, it can't be acknowledged" # Raiden node will start pinging as soon as a new channel # is established. We need to test if # a) there is our original message in the queue # b) there are only Ping message types in messages_decoded = [decode(m) for m in messages] assert ping_message in messages_decoded for message in messages_decoded: assert isinstance(message, Ping)
def test_ping(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() async_result = app0.raiden.protocol.send_raw_with_result( ping_encoded, app1.raiden.address, ) assert async_result.wait(2), 'The message was not processed' expected_messageid = messageid_from_data(ping_encoded, app1.raiden.address) messages_decoded = [decode(m) for m in messages] processed_message = next( decoded for decoded in messages_decoded if isinstance(decoded, Processed) and decoded.processed_message_identifier == expected_messageid ) # the ping message was sent and processed assert ping_encoded in messages assert processed_message
def test_healthcheck_with_normal_peer(raiden_network, token_addresses): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() token_address = token_addresses[0] address0 = app0.raiden.address address1 = app1.raiden.address graph0 = app0.raiden.token_to_channelgraph[token_address] graph1 = app1.raiden.token_to_channelgraph[token_address] # check the nodes have a channel assert graph0.token_address == graph1.token_address assert address1 in graph0.partneraddress_to_channel assert address0 in graph1.partneraddress_to_channel # check both have started the healthcheck assert address0 in app1.raiden.protocol.addresses_events assert address1 in app0.raiden.protocol.addresses_events # wait for the healthcheck task to send a ping gevent.sleep(app0.raiden.protocol.nat_keepalive_timeout) gevent.sleep(app1.raiden.protocol.nat_keepalive_timeout) decoded_messages = [decode(m) for m in set(messages)] ping_messages = get_messages_by_type(decoded_messages, Ping) assert ping_messages
def receive(self, data): # ignore large packets if len(data) > self.max_message_size: log.error('receive packet larger than maximum size', length=len(data)) return msghash = sha3(data) # check if we handled this message already, if so repeat Ack if msghash in self.sent_acks: return self.send_ack(*self.sent_acks[msghash]) # We ignore the sending endpoint as this can not be known w/ UDP msg = messages.decode(data) if isinstance(msg, Ack): # we might receive the same Ack more than once if msg.echo in self.number_of_tries: log.debug('ACK RECEIVED {} [echo={}]'.format( pex(self.raiden.address), pex(msg.echo))) del self.number_of_tries[msg.echo] else: log.debug('DUPLICATED ACK RECEIVED {} [echo={}]'.format( pex(self.raiden.address), pex(msg.echo))) else: assert isinstance(msg, Secret) or msg.sender self.raiden.on_message(msg, msghash)
def test_ping(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() async_result = app0.raiden.protocol.send_raw_with_result( ping_encoded, app1.raiden.address, ) assert async_result.wait(2), 'The message was not acknowledged' expected_echohash = sha3(ping_encoded + app1.raiden.address) messages_decoded = [decode(m) for m in messages] ack_message = next( decoded for decoded in messages_decoded if isinstance(decoded, Ack) and decoded.echo == expected_echohash ) # the ping message was sent and acknowledged assert ping_encoded in messages assert ack_message
def test_udp_ping_pong(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() ping_message = Ping(nonce=0) app0.raiden.sign(ping_message) ping_encoded = ping_message.encode() messageid = ('ping', ping_message.nonce, app1.raiden.address) async_result = app0.raiden.protocol.maybe_sendraw_with_result( app1.raiden.address, ping_encoded, messageid, ) assert async_result.wait(2), 'The message was not processed' messages_decoded = [decode(m) for m in messages] processed_message = next( pong for pong in messages_decoded if isinstance(pong, Pong) and pong.nonce == ping_message.nonce) # the ping message was sent and processed assert ping_encoded in messages assert processed_message
def receive(self, messagedata: bytes): """ Handle an UDP packet. """ # pylint: disable=unidiomatic-typecheck if len(messagedata) > self.UDP_MAX_MESSAGE_SIZE: log.error( 'INVALID MESSAGE: Packet larger than maximum size', node=pex(self.raiden.address), message=hexlify(messagedata), length=len(messagedata), ) return message = decode(messagedata) if type(message) == Pong: self.receive_pong(message) elif type(message) == Ping: self.receive_ping(message) elif type(message) == Delivered: self.receive_delivered(message) elif message is not None: self.receive_message(message) else: log.error( 'INVALID MESSAGE: Unknown cmdid', node=pex(self.raiden.address), message=hexlify(messagedata), )
def test_hash(): ping = Ping(nonce=0, current_protocol_version=constants.PROTOCOL_VERSION) ping.sign(signer) data = ping.encode() msghash = sha3(data) decoded_ping = decode(data) assert sha3(decoded_ping.encode()) == msghash
def receive(self, data): if len(data) > UDP_MAX_MESSAGE_SIZE: log.error('receive packet larger than maximum size', length=len(data)) return # Repeat the ACK if the message has been handled before echohash = sha3(data + self.raiden.address) if echohash in self.receivedhashes_to_acks: return self._maybe_send_ack(*self.receivedhashes_to_acks[echohash]) message = decode(data) if isinstance(message, Ack): self.receive_ack(message) elif isinstance(message, Ping): self.receive_ping(message, echohash) elif isinstance(message, SignedMessage): self.receive_message(message, echohash) elif log.isEnabledFor(logging.ERROR): log.error( 'Invalid message', message=hexlify(data), )
def receive(self, data): # ignore large packets if len(data) > self.max_message_size: log.error('receive packet larger than maximum size', length=len(data)) return msghash = sha3(data + self.raiden.address) # check if we handled this message already, if so repeat Ack if msghash in self.msghash_acks: return self._send_ack(*self.msghash_acks[msghash]) # We ignore the sending endpoint as this can not be known w/ UDP message = decode(data) if isinstance(message, Ack): ack_result = self.msghash_asyncresult[message.echo] if ack_result.ready(): if log.isEnabledFor(logging.INFO): log.info( 'DUPLICATED ACK RECEIVED node:%s [echo=%s]', pex(self.raiden.address), pex(message.echo) ) else: if log.isEnabledFor(logging.INFO): log.info( 'ACK RECEIVED node:%s [echo=%s]', pex(self.raiden.address), pex(message.echo) ) ack_result.set(True) elif message is not None: assert isinstance(message, Secret) or message.sender # this might exit with an exception self.raiden.on_message(message, msghash) # only send the Ack if the message was handled without exceptions ack = Ack( self.raiden.address, msghash, ) self.send_ack( message.sender, ack, ) else: # payload was not a valid message and decoding failed if log.isEnabledFor(logging.ERROR): log.error( 'could not decode message %s', pex(data), )
def test_ping_dropped_message(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking # mock transport with packet loss, every 3rd is lost, starting with first message UnreliableTransport.droprate = 3 RaidenProtocol.try_interval = 0.1 # for fast tests RaidenProtocol.repeat_messages = True messages = setup_messages_cb() UnreliableTransport.network.counter = 0 ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send_and_wait(app1.raiden.address, ping) gevent.sleep(1) assert len(messages) == 3 # Ping(dropped), Ping, Ack for i in [0, 1]: assert decode(messages[i]) == ping for i in [2]: decoded = decode(messages[i]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping.encode() + app1.raiden.address) messages = setup_messages_cb() assert not messages UnreliableTransport.network.counter = 2 # first message sent, 2nd dropped ping = Ping(nonce=1) app0.raiden.sign(ping) app0.raiden.protocol.send_and_wait(app1.raiden.address, ping) gevent.sleep(1) assert len(messages) == 4 # Ping, Ack(dropped), Ping, Ack for i in [0, 2]: assert decode(messages[i]) == ping for i in [1, 3]: decoded = decode(messages[i]) assert isinstance(decoded, Ack) assert decoded.echo == sha3(ping.encode() + app1.raiden.address) RaidenProtocol.repeat_messages = False
def test_direct_transfer_min_max(identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY, ADDRESS) assert decode(direct_transfer.encode()) == direct_transfer
def test_ack(): echo = sha3(privkey) msg = Ack(address, echo) assert msg.echo == echo d = msg.encode() msghash = sha3(d) msg2 = decode(d) assert msg2.echo == echo assert msg2.sender == address assert sha3(msg2.encode()) == msghash
def test_processed(): echo = sha3(b'random') processed_message = Processed(ADDRESS, echo) assert processed_message.echo == echo data = processed_message.encode() msghash = sha3(data) decoded_processed_message = decode(data) assert decoded_processed_message.echo == processed_message.echo assert decoded_processed_message.sender == processed_message.sender assert sha3(decoded_processed_message.encode()) == msghash
def test_encoding(): ping = Ping(nonce=0, current_protocol_version=constants.PROTOCOL_VERSION) ping.sign(signer) decoded_ping = decode(ping.encode()) assert isinstance(decoded_ping, Ping) assert decoded_ping.sender == ADDRESS == ping.sender assert ping.nonce == decoded_ping.nonce assert ping.signature == decoded_ping.signature assert ping.cmdid == decoded_ping.cmdid assert ping.hash == decoded_ping.hash
def test_refund_transfer_min_max(amount, payment_identifier, nonce, transferred_amount): refund_transfer = factories.create( factories.RefundTransferProperties( amount=amount, payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, )) assert decode(refund_transfer.encode()) == refund_transfer
def test_encoding(): ping = Ping(nonce=0, current_protocol_version=constants.PROTOCOL_VERSION) ping.sign(PRIVKEY) decoded_ping = decode(ping.encode()) assert isinstance(decoded_ping, Ping) assert decoded_ping.sender == ADDRESS == ping.sender assert ping.nonce == decoded_ping.nonce assert ping.signature == decoded_ping.signature assert ping.cmdid == decoded_ping.cmdid assert ping.hash == decoded_ping.hash
def test_refund_transfer_min_max(amount, identifier, nonce, transferred_amount): refund_transfer = make_refund_transfer( amount=amount, identifier=identifier, nonce=nonce, transferred_amount=transferred_amount, ) refund_transfer.sign(PRIVKEY, ADDRESS) assert decode(refund_transfer.encode()) == refund_transfer
def test_direct_transfer_min_max(payment_identifier, nonce, transferred_amount): direct_transfer = make_direct_transfer( payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) direct_transfer.sign(PRIVKEY) assert direct_transfer.sender == ADDRESS assert decode(direct_transfer.encode()) == direct_transfer
def test_encoding(): ping = Ping(nonce=0) ping.sign(PRIVKEY) decoded_ping = decode(ping.encode()) assert isinstance(decoded_ping, Ping) assert decoded_ping.sender == ADDRESS == ping.sender assert ping.nonce == decoded_ping.nonce assert ping.signature == decoded_ping.signature assert ping.cmdid == decoded_ping.cmdid assert ping.hash == decoded_ping.hash
def test_ack(): echo = sha3(PRIVKEY) ack = Ack(ADDRESS, echo) assert ack.echo == echo data = ack.encode() msghash = sha3(data) decoded_ack = decode(data) assert decoded_ack.echo == ack.echo assert decoded_ack.sender == ack.sender assert sha3(decoded_ack.encode()) == msghash
def test_refund_transfer_min_max(amount, payment_identifier, nonce, transferred_amount): refund_transfer = make_refund_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) refund_transfer.sign(PRIVKEY) assert refund_transfer.sender == ADDRESS assert decode(refund_transfer.encode()) == refund_transfer
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce, transferred_amount): mediated_transfer = make_mediated_transfer( amount=amount, payment_identifier=payment_identifier, nonce=nonce, fee=fee, transferred_amount=transferred_amount, ) mediated_transfer.sign(PRIVKEY) assert mediated_transfer.sender == ADDRESS assert decode(mediated_transfer.encode()) == mediated_transfer
def test_encoding(): p = Ping(nonce=0) with pytest.raises(SignatureMissingError): p.encode() p.sign(privkey) d = p.encode() p2 = decode(d) assert isinstance(p2, Ping) assert p2.sender == address == p.sender assert p.nonce == p2.nonce assert p.signature == p2.signature assert p.cmdid == p.cmdid assert p.hash == p2.hash
def test_ping_ordering(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking # mock transport with packet loss, every 3rd is lost, starting with first message droprate = UnreliableTransport.droprate = 3 RaidenProtocol.try_interval = 0.1 # for fast tests RaidenProtocol.repeat_messages = True messages = setup_messages_cb() UnreliableTransport.network.counter = 0 ping_amount = 5 hashes = [] for nonce in range(ping_amount): ping = Ping(nonce=nonce) app0.raiden.sign(ping) app0.raiden.protocol.send_and_wait(app1.raiden.address, ping) pinghash = sha3(ping.encode() + app1.raiden.address) hashes.append(pinghash) gevent.sleep(2) # give some time for messages to be handled expected_message_amount = ping_amount * droprate assert len(messages) == expected_message_amount for i in range(0, expected_message_amount, droprate): assert isinstance(decode(messages[i]), Ping) for i in range(1, expected_message_amount, droprate): assert isinstance(decode(messages[i]), Ping) for i, j in zip(range(2, expected_message_amount, droprate), range(ping_amount)): decoded = decode(messages[i]) assert isinstance(decoded, Ack) assert decoded.echo == hashes[j] RaidenProtocol.repeat_messages = False
def test_transfer(): apps = create_network(num_nodes=2, num_assets=1, channels_per_node=1) a0, a1 = apps messages = setup_messages_cb() # channels am0 = a0.raiden.assetmanagers.values()[0] am1 = a1.raiden.assetmanagers.values()[0] assert am0.asset_address == am1.asset_address c0 = am0.channels[a1.raiden.address] c1 = am1.channels[a0.raiden.address] b0 = c0.balance b1 = c1.balance amount = 10 target = a1.raiden.address assert target in am0.channels a0.raiden.api.transfer(am0.asset_address, amount, target=target) gevent.sleep(1) assert len(messages) == 2 # Transfer, Ack mt = decode(messages[0]) assert isinstance(mt, Transfer) assert mt.balance == b1 + amount ma = decode(messages[1]) assert isinstance(ma, Ack) assert ma.echo == mt.hash assert b1 + amount == c1.balance assert b0 - amount == c0.balance assert c0.locked.root == c1.partner.locked.root == c1.locked.root == ''
def test_processed(): message_identifier = random.randint(0, constants.UINT64_MAX) processed_message = Processed(message_identifier) processed_message.sign(PRIVKEY) assert processed_message.sender == ADDRESS assert processed_message.message_identifier == message_identifier data = processed_message.encode() decoded_processed_message = decode(data) assert decoded_processed_message.message_identifier == message_identifier assert processed_message.message_identifier == message_identifier assert decoded_processed_message.sender == processed_message.sender assert sha3(decoded_processed_message.encode()) == sha3(data)
def test_ping_dropped_message(): apps = create_network( num_nodes=2, num_assets=0, channels_per_node=0, transport_class=UnreliableTransport, ) app0, app1 = apps # pylint: disable=unbalanced-tuple-unpacking # mock transport with packet loss, every 3nd is lost, starting with first message UnreliableTransport.droprate = 3 RaidenProtocol.try_interval = 0.1 # for fast tests RaidenProtocol.repeat_messages = True messages = setup_messages_cb() UnreliableTransport.network.counter = 0 ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send(app1.raiden.address, ping) gevent.sleep(1) assert len(messages) == 3 # Ping(dropped), Ping, Ack for i in [0, 1]: assert decode(messages[i]) == ping for i in [2]: decoded = decode(messages[i]) assert isinstance(decoded, Ack) assert decoded.echo == ping.hash # try failing Ack messages = setup_messages_cb() assert not messages UnreliableTransport.network.counter = 2 # first message sent, 2nd dropped ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send(app1.raiden.address, ping) gevent.sleep(1) for message in messages: print decode(message) assert len(messages) == 4 # Ping, Ack(dropped), Ping, Ack for i in [0, 2]: assert decode(messages[i]) == ping for i in [1, 3]: decoded = decode(messages[i]) assert isinstance(decoded, Ack) assert decoded.echo == ping.hash RaidenProtocol.repeat_messages = False
def test_mediated_transfer(): nonce = balance = 1 asset = recipient = target = initiator = address hashlock = locksroot = sha3(address) amount = expiration = 1 lock = Lock(amount, expiration, hashlock) d = lock.encode() assert Lock.decode(d) == lock msg = MediatedTransfer(nonce, asset, balance, recipient, locksroot, lock, target, initiator, fee=0) msg.sign(privkey) dm = msg.encode() msg2 = decode(dm) assert msg2 == msg assert msg2.lock == lock
def test_direct_transfer(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking messages = setup_messages_cb() graph0 = list(app0.raiden.token_to_channelgraph.values())[0] graph1 = list(app1.raiden.token_to_channelgraph.values())[0] channel0 = graph0.partneraddress_to_channel[app1.raiden.address] channel1 = graph1.partneraddress_to_channel[app0.raiden.address] balance0 = channel0.balance balance1 = channel1.balance assert graph0.token_address == graph1.token_address assert app1.raiden.address in graph0.partneraddress_to_channel amount = 10 target = app1.raiden.address result = app0.raiden.direct_transfer_async( graph0.token_address, amount, target, identifier=1, ) assert result.wait(timeout=10) gevent.sleep(5) assert_synched_channels( channel0, balance0 - amount, [], channel1, balance1 + amount, [] ) decoded_messages = [decode(m) for m in messages] direct_messages = get_messages_by_type(decoded_messages, DirectTransfer) assert len(direct_messages) == 1 assert direct_messages[0].transferred_amount == amount assert_ack_for( app1, direct_messages[0], decoded_messages, )
def test_ping_unreachable(raiden_network): app0, app1 = raiden_network # pylint: disable=unbalanced-tuple-unpacking UnreliableTransport.droprate = 1 # drop everything to force disabling of re-sends RaidenProtocol.try_interval = 0.1 # for fast tests RaidenProtocol.repeat_messages = True messages = setup_messages_cb() UnreliableTransport.network.counter = 0 ping = Ping(nonce=0) app0.raiden.sign(ping) app0.raiden.protocol.send_and_wait(app1.raiden.address, ping) gevent.sleep(2) assert len(messages) == 5 # 5 dropped Pings for i, message in enumerate(messages): assert decode(message) == ping RaidenProtocol.repeat_messages = False
def test_mediated_transfer(): nonce = balance = 1 asset = recipient = target = initiator = ADDRESS hashlock = locksroot = sha3(ADDRESS) amount = expiration = 1 fee = 0 lock = Lock(amount, expiration, hashlock) mediated_transfer = MediatedTransfer( nonce, asset, balance, recipient, locksroot, lock, target, initiator, fee, ) mediated_transfer.sign(PRIVKEY) decoded_mediated_transfer = decode(mediated_transfer.encode()) assert decoded_mediated_transfer == mediated_transfer