Exemple #1
0
def test_pfs_rejects_capacity_update_with_wrong_channel_identifier(
    pathfinding_service_web3_mock, ):
    pathfinding_service_web3_mock.chain_id = ChainID(1)

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS)
    pathfinding_service_web3_mock.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelID(0),
        participant1=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        participant2=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        settle_timeout=15,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelID(0)] == (
        private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
    )

    message = get_updatepfs_message(
        channel_identifier=ChannelID(35),
        updating_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        other_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        privkey_signer=PRIVAT_KEY_EXAMPLE_1,
    )

    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_web3_mock.on_pfs_update(message)
    assert "unknown channel identifier in token network" in str(exinfo.value)
Exemple #2
0
def test_edge_weight(addresses):
    channel_id = ChannelID(1)
    participant1 = addresses[0]
    participant2 = addresses[1]
    settle_timeout = 15
    view = ChannelView(TokenNetworkAddress("0x11"), channel_id, participant1,
                       participant2, settle_timeout)
    amount = TokenAmount(int(1e18))  # one RDN

    # no penalty
    assert TokenNetwork.edge_weight(dict(),
                                    dict(view=view),
                                    amount=amount,
                                    fee_penalty=0) == 1

    # channel already used in a previous route
    assert (TokenNetwork.edge_weight({channel_id: 2},
                                     dict(view=view),
                                     amount=amount,
                                     fee_penalty=0) == 3)

    # absolute fee
    view.absolute_fee = FeeAmount(int(0.03e18))
    assert TokenNetwork.edge_weight(dict(),
                                    dict(view=view),
                                    amount=amount,
                                    fee_penalty=100) == 4

    # relative fee
    view.absolute_fee = FeeAmount(0)
    view.relative_fee = 0.01
    assert TokenNetwork.edge_weight(dict(),
                                    dict(view=view),
                                    amount=amount,
                                    fee_penalty=100) == 2
Exemple #3
0
def test_routing_simple(
    token_network_model: TokenNetwork,
    populate_token_network_case_1: None,
    addresses: List[Address],
):
    view01: ChannelView = token_network_model.G[addresses[0]][
        addresses[1]]["view"]
    view10: ChannelView = token_network_model.G[addresses[1]][
        addresses[0]]["view"]

    assert view01.deposit == 100
    assert view01.absolute_fee == 0
    assert view01.capacity == 90
    assert view10.capacity == 60

    # 0->2->3 is the shortest path, but has no capacity, so 0->1->4->3 is used
    paths = token_network_model.get_paths(addresses[0],
                                          addresses[3],
                                          value=TokenAmount(10),
                                          max_paths=1,
                                          hop_bias=1)
    assert len(paths) == 1
    assert paths[0] == {
        "path": [addresses[0], addresses[1], addresses[4], addresses[3]],
        "estimated_fee": 0,
    }

    # Not connected.
    with pytest.raises(NetworkXNoPath):
        token_network_model.get_paths(addresses[0],
                                      addresses[5],
                                      value=TokenAmount(10),
                                      max_paths=1)
Exemple #4
0
def test_routing_simple(
    token_network_model: TokenNetwork,
    populate_token_network_case_1: None,
    addresses: List[Address],
):
    view01: ChannelView = token_network_model.G[addresses[0]][
        addresses[1]]['view']
    view10: ChannelView = token_network_model.G[addresses[1]][
        addresses[0]]['view']

    assert view01.deposit == 100
    assert isclose(view01.relative_fee, DEFAULT_PERCENTAGE_FEE)
    assert view01.capacity == 90
    assert view10.capacity == 60

    # 0->2->3 is the shortest path, but has no capacity, so 0->1->4->3 is used
    paths = token_network_model.get_paths(
        addresses[0],
        addresses[3],
        value=10,
        max_paths=1,
        hop_bias=1,
    )
    assert len(paths) == 1
    assert paths[0] == {
        'path': [addresses[0], addresses[1], addresses[4], addresses[3]],
        'estimated_fee': 0,
    }

    # Not connected.
    with pytest.raises(NetworkXNoPath):
        token_network_model.get_paths(addresses[0],
                                      addresses[5],
                                      value=10,
                                      max_paths=1)
Exemple #5
0
def test_path_without_capacity(token_network_model: TokenNetwork,
                               addresses: List[Address]):
    """Channels without capacity must not cause unexpected exceptions.

    Regression test for https://github.com/raiden-network/raiden-services/issues/636
    """
    token_network_model.handle_channel_opened_event(
        channel_identifier=ChannelID(1),
        participant1=addresses[0],
        participant2=addresses[1],
    )
    token_network_model.handle_channel_opened_event(
        channel_identifier=ChannelID(2),
        participant1=addresses[1],
        participant2=addresses[2],
    )

    token_network_model.G[addresses[1]][
        addresses[2]]["view"].channel.capacity1 = 100
    path = Path(
        G=token_network_model.G,
        nodes=[addresses[0], addresses[1], addresses[2]],
        value=PaymentAmount(10),
        reachability_state=SimpleReachabilityContainer({}),
    )
    assert not path.is_valid
Exemple #6
0
def test_pfs_rejects_capacity_update_with_wrong_nonces(
    addresses: List[Address],
    pathfinding_service_mocked_listeners: PathfindingService,
):
    pathfinding_service_mocked_listeners.chain_id = 1

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        token_address=DEFAULT_TOKEN_ADDRESS,
    )

    pathfinding_service_mocked_listeners.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelIdentifier(0),
        participant1=addresses[0],
        participant2=addresses[1],
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[0],
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[1],
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelIdentifier(0)] == (
        addresses[0],
        addresses[1],
    )

    message = get_updatepfs_message(
        updating_participant=addresses[0],
        other_participant=addresses[1],
    )

    # Check first capacity update succeeded
    pathfinding_service_mocked_listeners.on_pfs_update(message)
    view_to_partner, view_from_partner = token_network.get_channel_views_for_partner(
        channel_identifier=ChannelIdentifier(0),
        updating_participant=addresses[0],
        other_participant=addresses[1],
    )
    assert view_to_partner.capacity == 90
    assert view_to_partner.update_nonce == 1
    assert view_from_partner.capacity == 110
    assert view_from_partner.update_nonce == 0

    # Send the same Capacity Update again - leads to an exception
    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_mocked_listeners.on_pfs_update(message)
    assert 'Capacity Update already received' in str(exinfo.value)
Exemple #7
0
def test_pfs_rejects_capacity_update_with_wrong_nonces(
    pathfinding_service_web3_mock, ):
    pathfinding_service_web3_mock.chain_id = ChainID(1)

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS)

    pathfinding_service_web3_mock.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelID(0),
        participant1=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        participant2=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelID(0),
        receiver=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelID(0),
        receiver=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelID(0)] == (
        private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
    )

    message = get_updatepfs_message(
        updating_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        other_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        privkey_signer=PRIVAT_KEY_EXAMPLE_1,
    )

    # Check first capacity update succeeded
    pathfinding_service_web3_mock.on_pfs_update(message)
    view_to_partner, view_from_partner = token_network.get_channel_views_for_partner(
        channel_identifier=ChannelID(0),
        updating_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        other_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
    )
    assert view_to_partner.capacity == 90
    assert view_to_partner.update_nonce == 1
    assert view_from_partner.capacity == 110
    assert view_from_partner.update_nonce == 0

    # Send the same Capacity Update again - leads to an exception
    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_web3_mock.on_pfs_update(message)
    assert "Capacity Update already received" in str(exinfo.value)
Exemple #8
0
def test_routing_result_order(
    token_network_model: TokenNetwork,
    populate_token_network_case_1: None,
    addresses: List[Address],
):
    paths = token_network_model.get_paths(
        addresses[0],
        addresses[2],
        value=10,
        max_paths=5,
        hop_bias=1,
    )
    # 5 paths requested, but only 3 are available
    assert len(paths) == 3
    assert paths[0] == {
        'path': [addresses[0], addresses[2]],
        'estimated_fee': 0,
    }
    assert paths[1] == {
        'path': [addresses[0], addresses[1], addresses[2]],
        'estimated_fee': 0,
    }
    assert paths[2] == {
        'path': [addresses[0], addresses[1], addresses[4], addresses[3], addresses[2]],
        'estimated_fee': 0,
    }
Exemple #9
0
def test_routing_benchmark(token_network_model: TokenNetwork,
                           populate_token_network_random: None):
    value = TokenAmount(100)
    G = token_network_model.G
    times = []
    start = time.time()
    for _ in range(100):
        tic = time.time()
        source, target = random.sample(G.nodes, 2)
        paths = token_network_model.get_paths(source,
                                              target,
                                              value=value,
                                              max_paths=5,
                                              bias=0.0)
        toc = time.time()
        times.append(toc - tic)
    end = time.time()
    for path_object in paths:
        path = path_object["path"]
        fees = path_object["estimated_fee"]
        for node1, node2 in zip(path[:-1], path[1:]):
            view: ChannelView = G[node1][node2]["view"]
            print("fee = ", view.absolute_fee, "capacity = ", view.capacity)
        print("fee sum = ", fees)
    print("Paths: ", paths)
    print("Mean runtime: ", sum(times) / len(times))
    print("Min runtime: ", min(times))
    print("Max runtime: ", max(times))
    print("Total runtime: ", end - start)
Exemple #10
0
    def create_token_network_for_address(
        self,
        token_network_address: Address,
        token_address: Address,
        block_number: int = 0,
    ):
        token_network = TokenNetwork(token_network_address, token_address)
        self.token_networks[token_network_address] = token_network

        log.debug('Creating token network model', token_network_address=token_network_address)
        token_network_listener = BlockchainListener(
            web3=self.web3,
            contract_manager=self.contract_manager,
            contract_address=token_network_address,
            contract_name=CONTRACT_TOKEN_NETWORK,
            required_confirmations=self.required_confirmations,
            poll_interval=self.poll_interval,
            sync_start_block=block_number,
        )

        # subscribe to event notifications from blockchain listener
        token_network_listener.add_confirmed_listener(
            create_channel_event_topics(),
            self.handle_channel_event,
        )
        token_network_listener.start()
        self.token_network_listeners.append(token_network_listener)
Exemple #11
0
def test_capacity_check(
    token_network_model: TokenNetwork,
    reachability_state: SimpleReachabilityContainer,
    addresses: List[Address],
):
    """Test that the mediation fees are included in the capacity check"""
    # First get a path without mediation fees. This must return the shortest path: 4->1->0
    paths = token_network_model.get_paths(
        source=addresses[4],
        target=addresses[0],
        value=PaymentAmount(35),
        max_paths=1,
        reachability_state=reachability_state,
    )
    index_paths = [addresses_to_indexes(p.nodes, addresses) for p in paths]
    assert index_paths == [[4, 1, 0]]

    # New let's add mediation fees to the channel 0->1.
    model_with_fees = deepcopy(token_network_model)
    model_with_fees.G[addresses[1]][
        addresses[0]]["view"].fee_schedule_sender.flat = 1
    # The transfer from 4->1 must now include 1 Token for the mediation fee
    # which will be payed for the 1->0 channel in addition to the payment
    # value of 35. But 35 + 1 exceeds the capacity for channel 4->1, which is
    # 35. So we should now get the next best route instead.
    paths = model_with_fees.get_paths(
        source=addresses[4],
        target=addresses[0],
        value=PaymentAmount(35),
        max_paths=1,
        reachability_state=reachability_state,
        fee_penalty=0,
    )
    index_paths = [addresses_to_indexes(p.nodes, addresses) for p in paths]
    assert index_paths == [[4, 1, 2, 0]]
Exemple #12
0
    def handle_token_network_created(self, event: ReceiveTokenNetworkCreatedEvent) -> None:
        network_address = TokenNetworkAddress(event.token_network_address)
        if not self.follows_token_network(network_address):
            log.info("Found new token network", **asdict(event))

            self.token_networks[network_address] = TokenNetwork(network_address)
            self.database.upsert_token_network(network_address)
Exemple #13
0
def test_routing_result_order(
    token_network_model: TokenNetwork,
    reachability_state: SimpleReachabilityContainer,
    addresses: List[Address],
):
    hex_addrs = [to_checksum_address(addr) for addr in addresses]
    paths = token_network_model.get_paths(
        source=addresses[0],
        target=addresses[2],
        value=PaymentAmount(10),
        max_paths=5,
        reachability_state=reachability_state,
    )
    # 5 paths requested, but only 2 are available
    assert len(paths) == 2
    assert paths[0].to_dict()["path"] == [
        hex_addrs[0], hex_addrs[1], hex_addrs[2]
    ]
    assert paths[0].to_dict()["estimated_fee"] == 0
    assert paths[1].to_dict()["path"] == [
        hex_addrs[0],
        hex_addrs[1],
        hex_addrs[4],
        hex_addrs[3],
        hex_addrs[2],
    ]
    assert paths[1].to_dict()["estimated_fee"] == 0
Exemple #14
0
def test_routing_benchmark(
    token_network_model: TokenNetwork,
    populate_token_network_random: None,
):
    value = 100
    G = token_network_model.G
    times = []
    start = time.time()
    for _ in range(100):
        tic = time.time()
        source, target = random.sample(G.nodes, 2)
        paths = token_network_model.get_paths(source,
                                              target,
                                              value=value,
                                              max_paths=5,
                                              bias=0.0)
        toc = time.time()
        times.append(toc - tic)
    end = time.time()
    for path_object in paths:
        path = path_object['path']
        fees = path_object['estimated_fee']
        for node1, node2 in zip(path[:-1], path[1:]):
            view: ChannelView = G[node1][node2]['view']
            print('fee = ', view.relative_fee, 'capacity = ', view.capacity)
        print('fee sum = ', fees)
    print('Paths: ', paths)
    print('Mean runtime: ', sum(times) / len(times))
    print('Min runtime: ', min(times))
    print('Max runtime: ', max(times))
    print('Total runtime: ', end - start)
Exemple #15
0
def test_edge_weight(addresses):
    a = addresses[0]
    b = addresses[1]
    view = ChannelView(1, a, b)

    assert TokenNetwork.edge_weight(
        dict(),
        dict(view=view),
    ) == 1
Exemple #16
0
def test_tn_idempotency_of_channel_openings(token_network_model: TokenNetwork,
                                            addresses: List[Address]):
    # create same channel 5 times
    for _ in range(5):
        token_network_model.handle_channel_opened_event(
            channel_identifier=ChannelID(1),
            participant1=addresses[0],
            participant2=addresses[1],
        )
    # there should only be one channel
    assert len(token_network_model.channel_id_to_addresses) == 1

    # now close the channel
    token_network_model.handle_channel_removed_event(
        channel_identifier=ChannelID(1))

    # there should be no channels
    assert len(token_network_model.channel_id_to_addresses) == 0
Exemple #17
0
def setup_channel(service: PathfindingService) -> TokenNetwork:
    token_network = TokenNetwork(token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS)
    service.token_networks[token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=DEFAULT_CHANNEL_ID,
        participant1=PRIVATE_KEY_1_ADDRESS,
        participant2=PRIVATE_KEY_2_ADDRESS,
        settle_timeout=15,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[DEFAULT_CHANNEL_ID] == (
        PRIVATE_KEY_1_ADDRESS,
        PRIVATE_KEY_2_ADDRESS,
    )

    return token_network
    def handle_token_network_created(
            self, event: ReceiveTokenNetworkCreatedEvent) -> None:
        network_address = event.token_network_address
        settle_timeout = event.settle_timeout
        if not self.follows_token_network(network_address):
            log.info("Found new token network", event_=event)

            self.token_networks[network_address] = TokenNetwork(
                network_address, settle_timeout)
            self.database.upsert_token_network(network_address, settle_timeout)
Exemple #19
0
def test_suggest_partner(
    token_network_model: TokenNetwork,
    addresses: List[Address],
):
    a = addresses  # pylint: disable=invalid-name

    reachability = SimpleReachabilityContainer(
        {a[i]: AddressReachability.REACHABLE
         for i in range(3)})
    suggestions = token_network_model.suggest_partner(reachability)
    assert len(suggestions) == 3
    assert set(s["address"] for s in suggestions) == set(
        to_checksum_address(a[i]) for i in range(3))
    assert suggestions[0]["address"] == to_checksum_address(a[1])

    # Increasing uptime of node 0 should move it to first place
    reachability.times[a[0]] -= timedelta(seconds=10)
    suggestions = token_network_model.suggest_partner(reachability)
    assert suggestions[0]["address"] == to_checksum_address(a[0])
Exemple #20
0
def test_routing_simple(
    token_network_model: TokenNetwork,
    reachability_state: SimpleReachabilityContainer,
    addresses: List[Address],
):
    hex_addrs = [to_checksum_address(addr) for addr in addresses]
    view01: ChannelView = token_network_model.G[addresses[0]][
        addresses[1]]["view"]
    view10: ChannelView = token_network_model.G[addresses[1]][
        addresses[0]]["view"]

    assert view01.fee_schedule_sender.flat == 0
    assert view01.capacity == 90
    assert view10.capacity == 60

    # 0->2->3 is the shortest path, but has no capacity.
    # The remaining paths are 0->1->2->3 and 0->1->4->3.
    paths = token_network_model.get_paths(
        source=addresses[0],
        target=addresses[3],
        value=PaymentAmount(10),
        max_paths=2,
        reachability_state=reachability_state,
    )
    assert len(paths) == 2
    assert paths[0].to_dict()["path"] == [
        hex_addrs[0], hex_addrs[1], hex_addrs[2], hex_addrs[3]
    ]
    assert paths[0].to_dict()["estimated_fee"] == 0
    assert paths[1].to_dict()["path"] == [
        hex_addrs[0], hex_addrs[1], hex_addrs[4], hex_addrs[3]
    ]
    assert paths[1].to_dict()["estimated_fee"] == 0

    # Not connected.
    no_paths = token_network_model.get_paths(
        source=addresses[0],
        target=addresses[5],
        value=PaymentAmount(10),
        max_paths=1,
        reachability_state=reachability_state,
    )
    assert [] == no_paths
Exemple #21
0
def test_edge_weight(addresses):
    channel_id = ChannelIdentifier(1)
    participant1 = addresses[0]
    participant2 = addresses[1]
    settle_timeout = 15
    view = ChannelView(channel_id, participant1, participant2, settle_timeout)

    assert TokenNetwork.edge_weight(
        dict(),
        dict(view=view),
    ) == 1
Exemple #22
0
def test_routing_result_order(token_network_model: TokenNetwork,
                              addresses: List[Address]):
    paths = token_network_model.get_paths(addresses[0],
                                          addresses[2],
                                          value=TokenAmount(10),
                                          max_paths=5)
    # 5 paths requested, but only 1 is available
    assert len(paths) == 1
    assert paths[0] == {
        "path": [addresses[0], addresses[1], addresses[2]],
        "estimated_fee": 0
    }
Exemple #23
0
def test_pfs_rejects_capacity_update_with_impossible_updating_capacity(
    pathfinding_service_web3_mock, ):
    pathfinding_service_web3_mock.chain_id = ChainID(1)

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS)

    pathfinding_service_web3_mock.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelID(0),
        participant1=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        participant2=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelID(0),
        receiver=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelID(0),
        receiver=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelID(0)] == (
        private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
    )

    with patch(
            "pathfinding_service.service.recover_signer_from_capacity_update",
            private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
    ):
        message = get_updatepfs_message(
            updating_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
            other_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
            updating_capacity=TokenAmount(UINT256_MAX),
            privkey_signer=PRIVAT_KEY_EXAMPLE_1,
        )
        message.updating_capacity = TokenAmount(UINT256_MAX + 1)

        with pytest.raises(InvalidCapacityUpdate) as exinfo:
            pathfinding_service_web3_mock.on_pfs_update(message)
        assert "with impossible updating_capacity" in str(exinfo.value)
Exemple #24
0
def test_routing_simple(
    token_network_model: TokenNetwork,
    address_to_reachability: Dict[Address, AddressReachability],
    addresses: List[Address],
):
    hex_addrs = [to_checksum_address(addr) for addr in addresses]
    view01: ChannelView = token_network_model.G[addresses[0]][
        addresses[1]]["view"]
    view10: ChannelView = token_network_model.G[addresses[1]][
        addresses[0]]["view"]

    assert view01.deposit == 100
    assert view01.fee_schedule_sender.flat == 0
    assert view01.capacity == 90
    assert view10.capacity == 60

    # 0->2->3 is the shortest path, but has no capacity, so 0->1->4->3 is used
    paths = token_network_model.get_paths(
        source=addresses[0],
        target=addresses[3],
        value=TokenAmount(10),
        max_paths=1,
        address_to_reachability=address_to_reachability,
    )
    assert len(paths) == 1
    assert paths[0] == {
        "path": [hex_addrs[0], hex_addrs[1], hex_addrs[4], hex_addrs[3]],
        "estimated_fee": 0,
    }

    # Not connected.
    with pytest.raises(NetworkXNoPath):
        token_network_model.get_paths(
            source=addresses[0],
            target=addresses[5],
            value=TokenAmount(10),
            max_paths=1,
            address_to_reachability=address_to_reachability,
        )
Exemple #25
0
def test_pfs_rejects_capacity_update_with_wrong_other_participant(
    addresses: List[Address],
    pathfinding_service_mocked_listeners: PathfindingService,
):
    pathfinding_service_mocked_listeners.chain_id = 1

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        token_address=DEFAULT_TOKEN_ADDRESS,
    )

    pathfinding_service_mocked_listeners.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelIdentifier(0),
        participant1=addresses[0],
        participant2=addresses[1],
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[0],
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[1],
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelIdentifier(0)] == (
        addresses[0],
        addresses[1],
    )

    message = get_updatepfs_message(
        updating_participant=addresses[0],
        other_participant=addresses[2],
    )

    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_mocked_listeners.on_pfs_update(message)
    assert 'Other Participant of Capacity Update does not match' in str(
        exinfo.value)
def test_routing_result_order(
    token_network_model: TokenNetwork,
    address_to_reachability: Dict[Address, AddressReachability],
    addresses: List[Address],
):
    hex_addrs = [to_checksum_address(addr) for addr in addresses]
    paths = token_network_model.get_paths(
        addresses[0],
        addresses[2],
        value=PaymentAmount(10),
        max_paths=5,
        address_to_reachability=address_to_reachability,
    )
    # 5 paths requested, but only 1 is available
    assert len(paths) == 1
    assert paths[0] == {"path": [hex_addrs[0], hex_addrs[1], hex_addrs[2]], "estimated_fee": 0}
Exemple #27
0
def test_routing_benchmark(token_network_model: TokenNetwork):  # pylint: disable=too-many-locals
    value = PaymentAmount(100)
    G = token_network_model.G
    addresses_to_reachabilities = SimpleReachabilityContainer({
        node: random.choice((
            AddressReachability.REACHABLE,
            AddressReachability.UNKNOWN,
            AddressReachability.UNREACHABLE,
        ))
        for node in G.nodes
    })

    times = []
    start = time.time()
    for _ in range(100):
        tic = time.time()
        source, target = random.sample(G.nodes, 2)
        paths = token_network_model.get_paths(
            source=source,
            target=target,
            value=value,
            max_paths=5,
            reachability_state=addresses_to_reachabilities,
        )

        toc = time.time()
        times.append(toc - tic)
    end = time.time()

    for path_object in paths:
        path = path_object.nodes
        fees = path_object.estimated_fee
        for node1, node2 in zip(path[:-1], path[1:]):
            view: ChannelView = G[to_canonical_address(node1)][
                to_canonical_address(node2)]["view"]
            print("capacity = ", view.capacity)
        print("fee sum = ", fees)
    print("Paths: ", paths)
    print("Mean runtime: ", sum(times) / len(times))
    print("Min runtime: ", min(times))
    print("Max runtime: ", max(times))
    print("Total runtime: ", end - start)
Exemple #28
0
def get_paths(  # pylint: disable=too-many-arguments
    token_network_model: TokenNetwork,
    reachability_state: SimpleReachabilityContainer,
    addresses: List[Address],
    source_index: int = 0,
    target_index: int = 8,
    value: PaymentAmount = PaymentAmount(10),
    max_paths: int = 5,
    diversity_penalty: float = DIVERSITY_PEN_DEFAULT,
) -> List:
    paths = token_network_model.get_paths(
        diversity_penalty=diversity_penalty,
        source=addresses[source_index],
        target=addresses[target_index],
        value=value,
        max_paths=max_paths,
        reachability_state=reachability_state,
    )
    index_paths = [addresses_to_indexes(p.nodes, addresses) for p in paths]
    return index_paths
Exemple #29
0
def get_paths(  # pylint: disable=too-many-arguments
    token_network_model: TokenNetwork,
    address_to_reachability: Dict[Address, AddressReachability],
    addresses: List[Address],
    source_index: int = 0,
    target_index: int = 8,
    value: TokenAmount = TokenAmount(10),
    max_paths: int = 5,
    diversity_penalty: float = DIVERSITY_PEN_DEFAULT,
) -> List:
    paths = token_network_model.get_paths(
        diversity_penalty=diversity_penalty,
        source=addresses[source_index],
        target=addresses[target_index],
        value=value,
        max_paths=max_paths,
        address_to_reachability=address_to_reachability,
    )
    index_paths = [addresses_to_indexes(p["path"], addresses) for p in paths]
    return index_paths
Exemple #30
0
def test_pfs_rejects_capacity_update_with_wrong_token_network_address(
    pathfinding_service_web3_mock, ):
    pathfinding_service_web3_mock.chain_id = ChainID(1)

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS)

    pathfinding_service_web3_mock.token_networks[
        token_network.address] = token_network

    message = get_updatepfs_message(
        token_network_address=TokenNetworkAddressBytes(
            decode_hex("0x" + "1" * 40)),
        updating_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_1),
        other_participant=private_key_to_address(PRIVAT_KEY_EXAMPLE_2),
        privkey_signer=PRIVAT_KEY_EXAMPLE_1,
    )

    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_web3_mock.on_pfs_update(message)
    assert "unknown token network" in str(exinfo.value)