Example #1
0
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)
Example #2
0
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)
Example #3
0
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
Example #4
0
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)
Example #5
0
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)
Example #6
0
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
Example #7
0
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)
Example #8
0
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
Example #9
0
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
Example #10
0
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
Example #11
0
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)
Example #13
0
    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),
            )
Example #14
0
    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),
            )
Example #15
0
    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
Example #17
0
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
Example #19
0
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
Example #20
0
    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),
            )
Example #21
0
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)
Example #22
0
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
Example #24
0
    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
Example #26
0
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
Example #27
0
    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),
            )
Example #28
0
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),
            )
Example #30
0
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
Example #31
0
    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),
                )
Example #32
0
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
Example #33
0
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
Example #34
0
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
Example #35
0
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
Example #36
0
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
Example #37
0
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
Example #38
0
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_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
Example #40
0
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
Example #41
0
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
Example #42
0
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
Example #43
0
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
Example #46
0
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
Example #47
0
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
Example #48
0
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)
Example #50
0
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
Example #51
0
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,
    )
Example #53
0
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
Example #54
0
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