Exemple #1
0
def initiator_init(
        raiden: 'RaidenService',
        transfer_identifier: PaymentID,
        transfer_amount: PaymentAmount,
        transfer_secret: Secret,
        token_network_identifier: TokenNetworkID,
        target_address: TargetAddress,
):

    msg = 'Should never end up initiating transfer with Secret 0x0'
    assert transfer_secret != constants.EMPTY_HASH, msg
    transfer_state = TransferDescriptionWithSecretState(
        raiden.default_registry.address,
        transfer_identifier,
        transfer_amount,
        token_network_identifier,
        InitiatorAddress(raiden.address),
        target_address,
        transfer_secret,
    )
    previous_address = None
    routes = routing.get_best_routes(
        chain_state=views.state_from_raiden(raiden),
        token_network_id=token_network_identifier,
        from_address=InitiatorAddress(raiden.address),
        to_address=target_address,
        amount=transfer_amount,
        previous_address=previous_address,
        config=raiden.config,
    )
    init_initiator_statechange = ActionInitInitiator(
        transfer_state,
        routes,
    )
    return init_initiator_statechange
Exemple #2
0
def initiator_init(
        raiden,
        transfer_identifier,
        transfer_amount,
        transfer_secret,
        token_network_identifier,
        target_address,
):

    transfer_state = TransferDescriptionWithSecretState(
        transfer_identifier,
        transfer_amount,
        token_network_identifier,
        raiden.address,
        target_address,
        transfer_secret,
    )
    previous_address = None
    routes = routing.get_best_routes(
        views.state_from_raiden(raiden),
        token_network_identifier,
        raiden.address,
        target_address,
        transfer_amount,
        previous_address,
    )
    init_initiator_statechange = ActionInitInitiator(
        transfer_state,
        routes,
    )
    return init_initiator_statechange
Exemple #3
0
def handle_message_refundtransfer(raiden: RaidenService, message: RefundTransfer):
    token_network_address = message.token_network_address
    from_transfer = lockedtransfersigned_from_message(message)
    chain_state = views.state_from_raiden(raiden)

    routes = get_best_routes(
        chain_state,
        token_network_address,
        raiden.address,
        from_transfer.target,
        from_transfer.lock.amount,
        message.sender,
    )

    role = views.get_transfer_role(
        chain_state,
        from_transfer.lock.secrethash,
    )

    if role == 'initiator':
        secret = random_secret()
        state_change = ReceiveTransferRefundCancelRoute(
            message.sender,
            routes,
            from_transfer,
            secret,
        )
    else:
        state_change = ReceiveTransferRefund(
            message.sender,
            from_transfer,
            routes,
        )

    raiden.handle_state_change(state_change)
def test_routing_mocked_pfs_bad_http_code(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    token_network_state, addresses, channel_states = create_square_network_topology(
        payment_network_state=payment_network_state,
        token_network_state=token_network_state,
        our_address=our_address,
    )
    address1, address2, address3 = addresses
    channel_state1, channel_state2 = channel_states

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    # channel 1 and 2 are flipped here, to see when the PFS gets called
    json_data = {
        'result': [
            {
                'path': [to_checksum_address(our_address), to_checksum_address(address2)],
                'fees': 0,
            },
            {
                'path': [to_checksum_address(our_address), to_checksum_address(address1)],
                'fees': 0,
            },
        ],
    }

    response = Mock()
    response.configure_mock(status_code=400)
    response.json = Mock(return_value=json_data)

    with patch.object(requests, 'get', return_value=response):
        routes = get_best_routes(
            chain_state=chain_state,
            token_network_id=token_network_state.address,
            from_address=our_address,
            to_address=address1,
            amount=50,
            previous_address=None,
            config={
                'services': {
                    'pathfinding_service_address': 'my-pfs',
                    'pathfinding_max_paths': 3,
                },
            },
        )
        assert routes[0].node_address == address1
        assert routes[0].channel_identifier == channel_state1.identifier
        assert routes[1].node_address == address2
        assert routes[1].channel_identifier == channel_state2.identifier
def test_routing_mocked_pfs_invalid_json_structure(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    token_network_state, addresses, channel_states = create_square_network_topology(
        payment_network_state=payment_network_state,
        token_network_state=token_network_state,
        our_address=our_address,
    )
    address1, address2, address3 = addresses
    channel_state1, channel_state2 = channel_states

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    response = Mock()
    response.configure_mock(status_code=400)
    response.json = Mock(return_value={})

    with patch.object(requests, 'get', return_value=response):
        routes = get_best_routes(
            chain_state=chain_state,
            token_network_id=token_network_state.address,
            from_address=our_address,
            to_address=address1,
            amount=50,
            previous_address=None,
            config={
                'services': {
                    'pathfinding_service_address': 'my-pfs',
                    'pathfinding_max_paths': 3,
                },
            },
        )
        assert routes[0].node_address == address1
        assert routes[0].channel_identifier == channel_state1.identifier
        assert routes[1].node_address == address2
        assert routes[1].channel_identifier == channel_state2.identifier
Exemple #6
0
def mediator_init(raiden, transfer: LockedTransfer):
    from_transfer = lockedtransfersigned_from_message(transfer)
    routes = routing.get_best_routes(
        views.state_from_raiden(raiden),
        from_transfer.balance_proof.token_network_identifier,
        raiden.address,
        from_transfer.target,
        from_transfer.lock.amount,
        transfer.sender,
    )
    from_route = RouteState(
        transfer.sender,
        from_transfer.balance_proof.channel_address,
    )
    init_mediator_statechange = ActionInitMediator(
        routes,
        from_route,
        from_transfer,
    )
    return init_mediator_statechange
def test_routing_mocked_pfs_request_error(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    token_network_state, addresses, channel_states = create_square_network_topology(
        payment_network_state=payment_network_state,
        token_network_state=token_network_state,
        our_address=our_address,
    )
    address1, address2, address3 = addresses
    channel_state1, channel_state2 = channel_states

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    with patch.object(requests, 'get', side_effect=requests.RequestException()):
        routes = get_best_routes(
            chain_state=chain_state,
            token_network_id=token_network_state.address,
            from_address=our_address,
            to_address=address1,
            amount=50,
            previous_address=None,
            config={
                'services': {
                    'pathfinding_service_address': 'my-pfs',
                    'pathfinding_max_paths': 3,
                },
            },
        )
        assert routes[0].node_address == address1
        assert routes[0].channel_identifier == channel_state1.identifier
        assert routes[1].node_address == address2
        assert routes[1].channel_identifier == channel_state2.identifier
def test_routing_priority(chain_state, token_network_state, one_to_n_address,
                          our_address):
    open_block_number = factories.make_block_number()
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()
    address4 = factories.make_address()
    pseudo_random_generator = random.Random()
    # Create a network with the following topology
    #
    # our  ----- 1/1 ----> (1)
    #  |                    |
    #  |                    |
    #  2/0                  x
    #  |                    |
    #  v                    v
    # (2)  ----- x ----->  (3)
    #  |                    |
    #  |                    |
    #  x                    x
    #  |                    |
    #  v                    v
    # (4)                  (4)

    channel_state1 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=1, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=1, address=address1),
        ))
    channel_state2 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=2, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address2),
        ))

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration1 = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_iteration2 = token_network.state_transition(
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=3),
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration3 = token_network.state_transition(
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration4 = token_network.state_transition(
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration5 = token_network.state_transition(
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change6 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address2,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    token_network.state_transition(
        token_network_state=channel_new_iteration5.new_state,
        state_change=channel_new_state_change6,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    # test routing priority with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
    }

    error_msg, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes, error_msg
    assert routes[0].next_hop_address == address1, error_msg
    assert routes[1].next_hop_address == address2, error_msg

    # number of hops overwrites refunding capacity (route over node 2 involves less hops)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes[0].next_hop_address == address2
    assert routes[1].next_hop_address == address1
def test_routing_issue2663(chain_state, token_network_state, one_to_n_address,
                           our_address):
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()
    address4 = factories.make_address()
    pseudo_random_generator = random.Random()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1) <------50------
    #  |                                    |
    #  |                                    |
    # 100                                  (4)
    #  |                                    ^
    #  v                                    |
    # (2)  ----- 100 --->  (3) <-------100---

    channel_state1 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=50, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address1),
        ))
    channel_state2 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=100, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address2),
        ))

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration1 = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_iteration2 = token_network.state_transition(
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=3),
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration3 = token_network.state_transition(
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_iteration4 = token_network.state_transition(
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=5),
        participant1=address1,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_iteration5 = token_network.state_transition(
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration5.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 5
    assert len(graph_state.network.edges()) == 5

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    error_msg, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes1, error_msg
    assert routes1[0].next_hop_address == address1, error_msg
    assert routes1[1].next_hop_address == address2, error_msg

    # test routing with node 2 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.UNREACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes1[0].next_hop_address == address1

    # test routing with node 3 offline
    # the routing doesn't care as node 3 is not directly connected
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.UNREACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes1[0].next_hop_address == address1
    assert routes1[1].next_hop_address == address2

    # test routing with node 1 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.UNREACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].next_hop_address == address2
def test_internal_routing_mediation_fees(chain_state, token_network_state,
                                         one_to_n_address, our_address):
    """
    Checks that requesting a route for a single-hop transfer
    will return the route with estimated_fee of zero.
    """
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    pseudo_random_generator = random.Random()

    direct_channel_state = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=50, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address1),
        ))

    # create new channels as participant
    direct_channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=direct_channel_state,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    direct_channel_new_iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=direct_channel_new_state_change,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    route_new_state_change = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address1,
        participant2=address2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    route_new_iteration = token_network.state_transition(
        token_network_state=direct_channel_new_iteration.new_state,
        state_change=route_new_state_change,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = route_new_iteration.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
    }

    # Routing to our direct partner would require 0 mediation fees.x
    _, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes[0].estimated_fee == 0

    # Routing to our address2 through address1 would charge 2%
    error_msg, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address2,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes, error_msg
    assert routes[0].estimated_fee == round(INTERNAL_ROUTING_DEFAULT_FEE_PERC *
                                            50), error_msg
Exemple #11
0
def test_routing_priority(
    chain_state,
    payment_network_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()
    address4 = factories.make_address()

    # Create a network with the following topology
    #
    # our  ----- 1/1 ----> (1)
    #  |                    |
    #  |                    |
    #  2/0                  x
    #  |                    |
    #  v                    v
    # (2)  ----- x ----->  (3)
    #  |                    |
    #  |                    |
    #  x                    x
    #  |                    |
    #  v                    v
    # (4)                  (4)

    channel_state1 = factories.make_channel(
        our_balance=1,
        our_address=our_address,
        partner_balance=1,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=2,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )

    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
    )

    channel_new_iteration5 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change6 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address2,
        participant2=address4,
        block_number=open_block_number,
    )

    token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration5.new_state,
        state_change=channel_new_state_change6,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    # test routing priority with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address1
    assert routes[1].node_address == address2

    # number of hops overwrites refunding capacity (route over node 2 involves less hops)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
    assert routes[1].node_address == address1

    # sufficient routing capacity overwrites refunding capacity
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=2,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2

    # availability overwrites refunding capacity (node 1 offline)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
Exemple #12
0
def test_routing_issue2663(
    chain_state,
    payment_network_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1)
    #  |                    ^
    #  |                    |
    # 100                  100
    #  |                    |
    #  v                    |
    # (2)  ----- 100 --->  (3)

    channel_state1 = factories.make_channel(
        our_balance=50,
        our_address=our_address,
        partner_balance=0,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=100,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )
    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 2 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_UNREACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2 == []

    # test routing with node 3 offline
    # the routing doesn't care as node 3 is not directly connected
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_UNREACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 1 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2
def test_participant_selection(raiden_network, token_addresses):
    # pylint: disable=too-many-locals
    registry_address = raiden_network[0].raiden.default_registry.address
    one_to_n_address = raiden_network[0].raiden.default_one_to_n_address
    token_address = token_addresses[0]
    # connect the first node - this will register the token and open the first channel
    # Since there is no other nodes available to connect to this call will do nothing more
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=TokenAmount(100))

    # Test invalid argument values
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=TokenAmount(-1))
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=TokenAmount(100),
            joinable_funds_target=2,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=TokenAmount(100),
            joinable_funds_target=-1,
        )

    # Call the connect endpoint for all but the first node
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect, registry_address,
            token_address, 100) for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_address_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        token_network_registry_address=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address) for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    exception = AssertionError("Unsaturated connection managers",
                               unsaturated_connection_managers)
    with gevent.Timeout(120, exception):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address,
                                        token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(connection_managers, registry_address,
                           token_address) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state, registry_address, token_address)
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            _, routes, _ = routing.get_best_routes(
                chain_state=node_state,
                token_network_address=network_state.address,
                one_to_n_address=one_to_n_address,
                from_address=app.raiden.address,
                to_address=target.raiden.address,
                amount=PaymentAmount(1),
                previous_address=None,
                pfs_config=None,
                privkey=b"",  # not used if pfs is not configured
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    for app in raiden_network:
        sender = app.raiden
        sender_channel = next(
            (channel_state for channel_state in RaidenAPI(
                sender).get_channel_list(registry_address=registry_address,
                                         token_address=token_address)
             if channel_state.our_state.contract_balance > 0
             and channel_state.partner_state.contract_balance > 0),
            None,
        )  # choose a fully funded channel from sender
        if sender_channel:
            break
    assert sender_channel
    registry_address = sender.default_registry.address

    receiver = next(
        app.raiden for app in raiden_network
        if app.raiden.address == sender_channel.partner_state.address)

    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1

    with gevent.Timeout(30, exception=ValueError("partner not reachable")):
        waiting.wait_for_healthy(sender, receiver.address, PaymentAmount(1))

    with watch_for_unlock_failures(*raiden_network):
        amount = PaymentAmount(1)
        RaidenAPI(sender).transfer_and_wait(registry_address,
                                            token_address,
                                            amount,
                                            receiver.address,
                                            transfer_timeout=10)

        with gevent.Timeout(
                30,
                exception=ValueError(
                    "timeout while waiting for incoming transaction")):
            wait_for_transaction(receiver, registry_address, token_address,
                                 sender.address)

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (sender_channel.settle_timeout *
               estimate_blocktime(connection_manager.raiden.rpc_client) * 10)
    assert timeout > 0

    channels = views.list_channelstate_for_tokennetwork(
        chain_state=views.state_from_raiden(connection_manager.raiden),
        token_network_registry_address=registry_address,
        token_address=token_address,
    )
    channel_identifiers = [channel.identifier for channel in channels]

    with gevent.Timeout(
            timeout, exception=ValueError("timeout while waiting for leave")):
        # sender leaves the network
        RaidenAPI(sender).token_network_leave(registry_address, token_address)

    with gevent.Timeout(timeout,
                        exception=ValueError(
                            f"Channels didnt get settled after {timeout}")):
        waiting.wait_for_settle(
            raiden=connection_manager.raiden,
            token_network_registry_address=registry_address,
            token_address=token_address,
            channel_ids=channel_identifiers,
            retry_timeout=0.1,
        )
def test_routing_issue2663(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1)
    #  |                    ^
    #  |                    |
    # 100                  100
    #  |                    |
    #  v                    |
    # (2)  ----- 100 --->  (3)

    channel_state1 = factories.make_channel(
        our_balance=50,
        our_address=our_address,
        partner_balance=0,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=100,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )
    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 2 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_UNREACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2 == []

    # test routing with node 3 offline
    # the routing doesn't care as node 3 is not directly connected
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_UNREACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 1 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2
Exemple #15
0
def get_best_routes_with_iou_request_mocked(
    chain_state,
    token_network_state,
    one_to_n_address,
    from_address,
    to_address,
    amount,
    iou_json_data=None,
):
    def iou_side_effect(*args, **kwargs):
        if args[0].endswith("/info"):
            return mocked_json_response({
                "price_info":
                5,
                "network_info": {
                    "chain_id":
                    42,
                    "token_network_registry_address":
                    to_checksum_address(
                        factories.make_token_network_registry_address()),
                    "user_deposit_address":
                    to_checksum_address(factories.make_address()),
                    "confirmed_block": {
                        "number": 11
                    },
                },
                "version":
                "0.0.3",
                "operator":
                "John Doe",
                "message":
                "This is your favorite pathfinding service",
                "payment_address":
                to_checksum_address(factories.make_address()),
                "matrix_server":
                "http://matrix.example.com",
            })
        else:
            assert "params" in kwargs
            body = kwargs["params"]

            assert is_hex_address(body["sender"])
            assert is_hex_address(body["receiver"])
            assert "timestamp" in body
            assert is_hex(body["signature"])
            assert len(body["signature"]
                       ) == 65 * 2 + 2  # 65 hex encoded bytes with 0x prefix

            return mocked_json_response(response_data=iou_json_data)

    with patch.object(session, "get", side_effect=iou_side_effect) as patched:
        _, best_routes, feedback_token = get_best_routes(
            chain_state=chain_state,
            token_network_address=token_network_state.address,
            one_to_n_address=one_to_n_address,
            from_address=from_address,
            to_address=to_address,
            amount=amount,
            previous_address=None,
            pfs_config=PFS_CONFIG,
            privkey=PRIVKEY,
        )
        assert_checksum_address_in_url(patched.call_args[0][0])
        return best_routes, feedback_token
Exemple #16
0
 def get_best_routes_with_fees(*args, **kwargs):
     error_msg, routes, uuid = get_best_routes(*args, **kwargs)
     for r in routes:
         r.estimated_fee = fee_without_margin
     return error_msg, routes, uuid
def test_participant_selection(raiden_network, token_addresses, skip_if_tester):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address,
        token_address,
        100,
    )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        )

        for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address,
        ) for app in raiden_network
    ]

    assert wait_for_saturated(
        connection_managers,
        registry_address,
        token_address,
    ) is True

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                node_state,
                network_state.address,
                app.raiden.address,
                target.raiden.address,
                1,
                None,
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    sender = raiden_network[-1].raiden
    receiver = raiden_network[0].raiden

    registry_address = sender.default_registry.address
    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    # assert there is a direct channel sender -> receiver
    sender_channel = RaidenAPI(sender).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=receiver.address,
    )
    assert len(sender_channel) == 1
    sender_channel = sender_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (
        sender_channel.settle_timeout *
        connection_manager.raiden.chain.estimate_blocktime() *
        10
    )

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        RaidenAPI(raiden_network[0].raiden).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    wait_until_block(
        connection_manager.raiden.chain,
        before_block + wait_blocks,
    )
    wait_until_block(
        receiver.chain,
        before_block + wait_blocks,
    )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert receiver_channel[0].settle_transaction is not None
def test_participant_selection(raiden_network, token_addresses, skip_if_tester):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address,
        token_address,
        100,
    )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        )

        for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address,
        ) for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    with gevent.Timeout(
        120,
        AssertionError('Unsaturated connection managers', unsaturated_connection_managers),
    ):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address, token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                node_state,
                network_state.address,
                app.raiden.address,
                target.raiden.address,
                1,
                None,
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    sender = raiden_network[-1].raiden
    receiver = raiden_network[0].raiden

    registry_address = sender.default_registry.address
    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    # assert there is a direct channel sender -> receiver
    sender_channel = RaidenAPI(sender).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=receiver.address,
    )
    assert len(sender_channel) == 1
    sender_channel = sender_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (
        sender_channel.settle_timeout *
        connection_manager.raiden.chain.estimate_blocktime() *
        10
    )

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        RaidenAPI(raiden_network[0].raiden).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    wait_until_block(
        connection_manager.raiden.chain,
        before_block + wait_blocks,
    )
    wait_until_block(
        receiver.chain,
        before_block + wait_blocks,
    )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert receiver_channel[0].settle_transaction is not None
def run_test_participant_selection(raiden_network, token_addresses):
    # pylint: disable=too-many-locals
    registry_address = raiden_network[0].raiden.default_registry.address
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=100,
    )

    # Test invalid argument values
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=-1,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=2,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=-1,
        )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        ) for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address, ) for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    exception = AssertionError('Unsaturated connection managers',
                               unsaturated_connection_managers)
    with gevent.Timeout(120, exception):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address,
                                        token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                chain_state=node_state,
                token_network_id=network_state.address,
                from_address=app.raiden.address,
                to_address=target.raiden.address,
                amount=1,
                previous_address=None,
                config={},
                privkey=b'',  # not used if pfs is not configured
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    for app in raiden_network:
        sender = app.raiden
        sender_channel = next(
            (channel_state
             for channel_state in RaidenAPI(sender).get_channel_list(
                 registry_address=registry_address,
                 token_address=token_address,
             ) if channel_state.our_state.contract_balance > 0
             and channel_state.partner_state.contract_balance > 0),
            None,
        )  # choose a fully funded channel from sender
        if sender_channel:
            break
    registry_address = sender.default_registry.address

    receiver = next(
        app.raiden for app in raiden_network
        if app.raiden.address == sender_channel.partner_state.address)

    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (sender_channel.settle_timeout *
               connection_manager.raiden.chain.estimate_blocktime() * 10)
    assert timeout > 0

    channels = views.list_channelstate_for_tokennetwork(
        chain_state=views.state_from_raiden(connection_manager.raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    channel_identifiers = [channel.identifier for channel in channels]

    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        # sender leaves the network
        RaidenAPI(sender).token_network_leave(
            registry_address,
            token_address,
        )

    exception = ValueError(f'Channels didnt get settled after {timeout}')
    with gevent.Timeout(timeout, exception=exception):
        waiting.wait_for_settle(
            raiden=connection_manager.raiden,
            payment_network_id=registry_address,
            token_address=token_address,
            channel_ids=channel_identifiers,
            retry_timeout=0.1,
        )
def test_participant_selection(raiden_network, token_addresses):
    registry_address = raiden_network[0].raiden.default_registry.address

    # pylint: disable=too-many-locals
    token_address = token_addresses[0]

    # connect the first node (will register the token if necessary)
    RaidenAPI(raiden_network[0].raiden).token_network_connect(
        registry_address=registry_address,
        token_address=token_address,
        funds=100,
    )

    # Test invalid argument values
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=-1,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=2,
        )
    with pytest.raises(InvalidAmount):
        RaidenAPI(raiden_network[0].raiden).token_network_connect(
            registry_address=registry_address,
            token_address=token_address,
            funds=100,
            joinable_funds_target=-1,
        )

    # connect the other nodes
    connect_greenlets = [
        gevent.spawn(
            RaidenAPI(app.raiden).token_network_connect,
            registry_address,
            token_address,
            100,
        )
        for app in raiden_network[1:]
    ]
    gevent.wait(connect_greenlets)

    token_network_registry_address = views.get_token_network_identifier_by_token_address(
        views.state_from_raiden(raiden_network[0].raiden),
        payment_network_id=registry_address,
        token_address=token_address,
    )
    connection_managers = [
        app.raiden.connection_manager_for_token_network(
            token_network_registry_address,
        )
        for app in raiden_network
    ]

    unsaturated_connection_managers = connection_managers[:]
    with gevent.Timeout(
        120,
        AssertionError('Unsaturated connection managers', unsaturated_connection_managers),
    ):
        while unsaturated_connection_managers:
            for manager in unsaturated_connection_managers:
                if is_manager_saturated(manager, registry_address, token_address):
                    unsaturated_connection_managers.remove(manager)
            gevent.sleep(1)

    assert saturated_count(
        connection_managers,
        registry_address,
        token_address,
    ) == len(connection_managers)

    # ensure unpartitioned network
    for app in raiden_network:
        node_state = views.state_from_raiden(app.raiden)
        network_state = views.get_token_network_by_token_address(
            node_state,
            registry_address,
            token_address,
        )
        assert network_state is not None
        for target in raiden_network:
            if target.raiden.address == app.raiden.address:
                continue
            routes = routing.get_best_routes(
                node_state,
                network_state.address,
                app.raiden.address,
                target.raiden.address,
                1,
                None,
            )
            assert routes is not None

    # create a transfer to the leaving node, so we have a channel to settle
    for app in raiden_network:
        sender = app.raiden
        sender_channel = next((
            channel_state
            for channel_state in RaidenAPI(sender).get_channel_list(
                registry_address=registry_address,
                token_address=token_address,
            )
            if channel_state.our_state.contract_balance > 0 and
            channel_state.partner_state.contract_balance > 0
        ), None)  # choose a fully funded channel from sender
        if sender_channel:
            break
    registry_address = sender.default_registry.address

    receiver = next(
        app.raiden for app in raiden_network
        if app.raiden.address == sender_channel.partner_state.address
    )

    # assert there is a direct channel receiver -> sender (vv)
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    assert len(receiver_channel) == 1
    receiver_channel = receiver_channel[0]

    exception = ValueError('partner not reachable')
    with gevent.Timeout(30, exception=exception):
        waiting.wait_for_healthy(sender, receiver.address, 1)

    amount = 1
    RaidenAPI(sender).transfer_and_wait(
        registry_address,
        token_address,
        amount,
        receiver.address,
        transfer_timeout=10,
    )

    exception = ValueError('timeout while waiting for incoming transaction')
    with gevent.Timeout(30, exception=exception):
        wait_for_transaction(
            receiver,
            registry_address,
            token_address,
            sender.address,
        )

    # test `leave()` method
    connection_manager = connection_managers[0]

    timeout = (
        sender_channel.settle_timeout *
        connection_manager.raiden.chain.estimate_blocktime() *
        10
    )

    assert timeout > 0
    exception = ValueError('timeout while waiting for leave')
    with gevent.Timeout(timeout, exception=exception):
        # sender leaves the network
        RaidenAPI(sender).token_network_leave(
            registry_address,
            token_address,
        )

    before_block = connection_manager.raiden.chain.block_number()
    wait_blocks = sender_channel.settle_timeout + 10
    # wait until both chains are synced?
    wait_until_block(
        connection_manager.raiden.chain,
        before_block + wait_blocks,
    )
    wait_until_block(
        receiver.chain,
        before_block + wait_blocks,
    )
    receiver_channel = RaidenAPI(receiver).get_channel_list(
        registry_address=registry_address,
        token_address=token_address,
        partner_address=sender.address,
    )
    # because of timing, channel may already have been cleaned
    assert not receiver_channel or receiver_channel[0].settle_transaction is not None
def test_routing_priority(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()
    pkey4, address4 = factories.make_privkey_address()

    # Create a network with the following topology
    #
    # our  ----- 1/1 ----> (1)
    #  |                    |
    #  |                    |
    #  2/0                  x
    #  |                    |
    #  v                    v
    # (2)  ----- x ----->  (3)
    #  |                    |
    #  |                    |
    #  x                    x
    #  |                    |
    #  v                    v
    # (4)                  (4)

    channel_state1 = factories.make_channel(
        our_balance=1,
        our_address=our_address,
        partner_balance=1,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=2,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )

    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
    )

    channel_new_iteration5 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change6 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address2,
        participant2=address4,
        block_number=open_block_number,
    )

    token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration5.new_state,
        state_change=channel_new_state_change6,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    # test routing priority with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address1
    assert routes[1].node_address == address2

    # number of hops overwrites refunding capacity (route over node 2 involves less hops)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
    assert routes[1].node_address == address1

    # sufficient routing capacity overwrites refunding capacity
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=2,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2

    # availability overwrites refunding capacity (node 1 offline)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
Exemple #22
0
def test_routing_mocked_pfs_unavailabe_peer(
    chain_state,
    payment_network_state,
    token_network_state,
    our_address,
):
    token_network_state, addresses, channel_states = create_square_network_topology(
        payment_network_state=payment_network_state,
        token_network_state=token_network_state,
        our_address=our_address,
    )
    address1, address2, address3 = addresses
    _, channel_state2 = channel_states

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    # channel 1 and 2 are flipped here, to see when the PFS gets called
    json_data = {
        'result': [
            {
                'path': [
                    to_checksum_address(our_address),
                    to_checksum_address(address2)
                ],
                'fees':
                0,
            },
            {
                'path': [
                    to_checksum_address(our_address),
                    to_checksum_address(address1)
                ],
                'fees':
                0,
            },
        ],
    }

    # test routing with node 2 unavailable
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_UNREACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    response = Mock()
    response.configure_mock(status_code=200)
    response.json = Mock(return_value=json_data)

    with patch.object(requests, 'post', return_value=response):
        routes = get_best_routes(
            chain_state=chain_state,
            token_network_id=token_network_state.address,
            from_address=our_address,
            to_address=address1,
            amount=50,
            previous_address=None,
            config={
                'services': {
                    'pathfinding_service_address': 'my-pfs',
                    'pathfinding_max_paths': 3,
                },
            },
        )
        assert routes[0].node_address == address2
        assert routes[0].channel_identifier == channel_state2.identifier