예제 #1
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)
예제 #2
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)
예제 #3
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
예제 #4
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]]
예제 #5
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)
예제 #6
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)
예제 #7
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,
    }
예제 #8
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
예제 #9
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
    }
예제 #10
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,
        )
예제 #11
0
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}
예제 #12
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)
예제 #13
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
예제 #14
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