def test_mediator_skips_used_routes():
    prng = random.Random()
    block_number = 3
    defaults = factories.NettingChannelStateProperties(
        our_state=factories.NettingChannelEndStateProperties.OUR_STATE,
        partner_state=factories.NettingChannelEndStateProperties(
            balance=UNIT_TRANSFER_AMOUNT),
        open_transaction=factories.TransactionExecutionStatusProperties(
            started_block_number=1, finished_block_number=2, result="success"),
    )
    properties = [
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP1_KEY, address=factories.HOP1)),
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP2_KEY, address=factories.HOP2)),
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP3_KEY, address=factories.HOP3)),
    ]
    channels = factories.make_channel_set(properties=properties,
                                          number_of_channels=3,
                                          defaults=defaults)
    bob = channels.channels[1].partner_state.address
    charlie = channels.channels[2].partner_state.address
    dave = factories.make_address()
    eric = factories.make_address()
    locked_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=10,
            routes=[
                [
                    factories.UNIT_OUR_ADDRESS, bob, dave,
                    factories.UNIT_TRANSFER_TARGET
                ],
                [
                    factories.UNIT_OUR_ADDRESS, bob, eric,
                    factories.UNIT_TRANSFER_TARGET
                ],
                [
                    factories.UNIT_OUR_ADDRESS, charlie, eric,
                    factories.UNIT_TRANSFER_TARGET
                ],
            ],
            canonical_identifier=channels.channels[0].canonical_identifier,
            pkey=factories.HOP1_KEY,
            sender=factories.HOP1,
        ))
    init_action = factories.mediator_make_init_action(channels=channels,
                                                      transfer=locked_transfer)
    nodeaddresses_to_networkstates = {
        channel.partner_state.address: NetworkState.REACHABLE
        for channel in channels.channels
    }

    transition_result = mediator.handle_init(
        state_change=init_action,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )
    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events

    assert len(mediator_state.routes) == 3
    assert mediator_state.routes[0].route[1] == bob
    assert mediator_state.routes[1].route[1] == bob
    assert mediator_state.routes[2].route[1] == charlie
    # now we receive a refund from whoever we forwarded to (should be HOP2)
    assert isinstance(events[-1], SendLockedTransfer)
    assert events[-1].recipient == factories.HOP2

    last_pair = mediator_state.transfers_pair[-1]
    canonical_identifier = last_pair.payee_transfer.balance_proof.canonical_identifier
    lock_expiration = last_pair.payee_transfer.lock.expiration
    payment_identifier = last_pair.payee_transfer.payment_identifier

    received_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=lock_expiration,
            payment_identifier=payment_identifier,
            canonical_identifier=canonical_identifier,
            sender=factories.HOP2,
            pkey=factories.HOP2_KEY,
            message_identifier=factories.make_message_identifier(),
        ))

    refund_state_change = ReceiveTransferRefund(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
    )
    transition_result = mediator.handle_refundtransfer(
        mediator_state=mediator_state,
        mediator_state_change=refund_state_change,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )

    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events
    assert mediator_state.transfers_pair[-1].payee_address == charlie

    # now we should have a forward transfer to HOP3
    assert isinstance(events[-1], SendLockedTransfer)
    assert events[-1].recipient == factories.HOP3

    # now we will receive a refund from HOP3

    last_pair = mediator_state.transfers_pair[-1]
    canonical_identifier = last_pair.payee_transfer.balance_proof.canonical_identifier
    lock_expiration = last_pair.payee_transfer.lock.expiration
    payment_identifier = last_pair.payee_transfer.payment_identifier

    received_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=lock_expiration,
            payment_identifier=payment_identifier,
            canonical_identifier=canonical_identifier,
            sender=factories.HOP3,
            pkey=factories.HOP3_KEY,
            message_identifier=factories.make_message_identifier(),
        ))

    refund_state_change = ReceiveTransferRefund(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    transition_result = mediator.handle_refundtransfer(
        mediator_state=mediator_state,
        mediator_state_change=refund_state_change,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )

    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events

    # no other routes available, so refund HOP1
    assert isinstance(events[-1], SendRefundTransfer)
    assert events[-1].recipient == factories.HOP1
Exemple #2
0
def test_mediator_task_view():
    """Same as above for mediator tasks."""
    secret1 = factories.make_secret(1)
    locked_amount1 = TokenAmount(11)
    payee_transfer = factories.create(
        factories.LockedTransferUnsignedStateProperties(secret=secret1))
    payer_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=secret1,
            payment_identifier=PaymentID(1),
            locked_amount=locked_amount1))
    secrethash1 = payee_transfer.lock.secrethash
    initiator = payee_transfer.initiator
    initiator_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                address=initiator, balance=TokenAmount(100))))
    route_state = RouteState(
        route=[payee_transfer.target],
        forward_channel_id=initiator_channel.canonical_identifier.
        channel_identifier,
    )

    transfer_state1 = MediatorTransferState(secrethash=secrethash1,
                                            routes=[route_state])
    # pylint: disable=E1101
    transfer_state1.transfers_pair.append(
        MediationPairState(
            payer_transfer=payer_transfer,
            payee_transfer=payee_transfer,
            payee_address=payee_transfer.target,
        ))
    task1 = MediatorTask(
        token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state1)

    secret2 = factories.make_secret(2)
    locked_amount2 = TokenAmount(13)
    transfer2 = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=secret2,
            payment_identifier=PaymentID(2),
            locked_amount=locked_amount2))
    secrethash2 = transfer2.lock.secrethash
    transfer_state2 = MediatorTransferState(secrethash=secrethash2,
                                            routes=[route_state])
    transfer_state2.waiting_transfer = WaitingTransferState(transfer=transfer2)
    task2 = MediatorTask(
        token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state2)

    payment_mapping = {
        secrethash1: cast(TransferTask, task1),
        secrethash2: cast(TransferTask, task2),
    }
    view = transfer_tasks_view(payment_mapping)

    assert len(view) == 2
    if view[0].get("payment_identifier") == "1":
        pending_transfer, waiting_transfer = view
    else:
        waiting_transfer, pending_transfer = view

    assert pending_transfer.get("role") == waiting_transfer.get(
        "role") == "mediator"
    assert pending_transfer.get("payment_identifier") == "1"
    assert waiting_transfer.get("payment_identifier") == "2"
    assert pending_transfer.get("locked_amount") == str(locked_amount1)
    assert waiting_transfer.get("locked_amount") == str(locked_amount2)
def test_initiator_skips_used_routes():
    defaults = factories.NettingChannelStateProperties(
        our_state=factories.NettingChannelEndStateProperties.OUR_STATE,
        partner_state=factories.NettingChannelEndStateProperties(balance=10),
        open_transaction=factories.TransactionExecutionStatusProperties(
            started_block_number=1, finished_block_number=2, result="success"),
    )
    properties = [
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP1_KEY, address=factories.HOP1))
    ]
    test_chain_state = factories.make_chain_state(number_of_channels=1,
                                                  properties=properties,
                                                  defaults=defaults)
    channels = test_chain_state.channel_set

    bob = channels.channels[0].partner_state.address

    routes = [[
        factories.UNIT_OUR_ADDRESS, bob, factories.UNIT_TRANSFER_TARGET
    ]]

    transfer = factories.create(
        factories.TransferDescriptionProperties(
            initiator=factories.UNIT_OUR_ADDRESS,
            target=factories.UNIT_TRANSFER_TARGET))
    init_action = factories.initiator_make_init_action(
        channels=channels,
        routes=routes,
        transfer=transfer,
        estimated_fee=FeeAmount(0))
    transition_result = handle_action_init_initiator(
        chain_state=test_chain_state.chain_state, state_change=init_action)

    chain_state = transition_result.new_state

    assert transfer.secrethash in chain_state.payment_mapping.secrethashes_to_task

    initiator_task = chain_state.payment_mapping.secrethashes_to_task[
        transfer.secrethash]
    initiator_state = initiator_task.manager_state

    assert len(initiator_state.routes) == 1, "Should have one route"
    assert len(
        initiator_state.routes[0].route) == 3, "Route should not be pruned"
    assert initiator_state.routes[0].route == routes[
        0], "Should have test route"

    events = transition_result.events

    assert isinstance(events[-1], SendLockedTransfer)

    locked_transfer = initiator_state.initiator_transfers[
        transfer.secrethash].transfer

    received_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=locked_transfer.lock.expiration,
            payment_identifier=locked_transfer.payment_identifier,
            canonical_identifier=locked_transfer.balance_proof.
            canonical_identifier,
            initiator=factories.UNIT_OUR_ADDRESS,
            sender=bob,
            pkey=factories.HOP1_KEY,
            message_identifier=factories.make_message_identifier(),
            routes=[],
            secret=transfer.secret,
        ))

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

    assert role == "initiator", "Should keep initiator role"

    failed_route_state_change = ReceiveTransferCancelRoute(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    state_transition(chain_state=chain_state,
                     state_change=failed_route_state_change)

    reroute_state_change = ActionTransferReroute(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
        secret=factories.make_secret(),
    )

    iteration = state_transition(chain_state=chain_state,
                                 state_change=reroute_state_change)

    assert search_for_item(iteration.events, SendLockedTransfer, {}) is None
Exemple #4
0
def test_routing_priority(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()

    # 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,
    )

    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,
    )

    # 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(),
    )

    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(),
    )

    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(),
    )

    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(),
    )

    # 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,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
        privkey=b"",
    )
    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,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        config={},
        privkey=b"",
    )
    assert routes[0].node_address == address2
    assert routes[1].node_address == address1
Exemple #5
0
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()

    # 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,
    )

    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,
    )

    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(),
    )

    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(),
    )

    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(),
    )

    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: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        config={},
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes1[0].node_address == address1
    assert routes1[1].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,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        config={},
        privkey=b"",
    )
    assert routes1[0].node_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: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_UNREACHABLE,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        config={},
        privkey=b"",
    )
    assert routes1[0].node_address == address1
    assert routes1[1].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,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=50,
        previous_address=None,
        config={},
        privkey=b"",
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].node_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 #7
0
def test_mediator_task_view():
    """Same as above for mediator tasks."""
    secret1 = factories.make_secret(1)
    locked_amount1 = 11
    payee_transfer = factories.create(
        factories.LockedTransferProperties(secret=secret1))
    payer_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                secret=secret1,
                payment_identifier=1,
                balance_proof=factories.BalanceProofProperties(
                    locked_amount=locked_amount1, ),
            ), ))
    secrethash1 = payee_transfer.lock.secrethash
    initiator = payee_transfer.initiator
    initiator_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                address=initiator, balance=100), ))
    routes = [factories.route_from_channel(initiator_channel)]
    transfer_state1 = MediatorTransferState(secrethash=secrethash1,
                                            routes=routes)
    transfer_state1.transfers_pair.append(
        MediationPairState(
            payer_transfer=payer_transfer,
            payee_transfer=payee_transfer,
            payee_address=payee_transfer.target,
        ))
    task1 = MediatorTask(
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state1,
    )

    secret2 = factories.make_secret(2)
    locked_amount2 = 13
    transfer2 = factories.create(
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                secret=secret2,
                payment_identifier=2,
                balance_proof=factories.BalanceProofProperties(
                    locked_amount=locked_amount2, ),
            ), ))
    secrethash2 = transfer2.lock.secrethash
    transfer_state2 = MediatorTransferState(secrethash=secrethash2,
                                            routes=routes)
    transfer_state2.waiting_transfer = WaitingTransferState(transfer=transfer2)
    task2 = MediatorTask(
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state2,
    )

    payment_mapping = {secrethash1: task1, secrethash2: task2}
    view = transfer_tasks_view(payment_mapping)

    assert len(view) == 2
    if view[0].get('payment_identifier') == '1':
        pending_transfer, waiting_transfer = view
    else:
        waiting_transfer, pending_transfer = view

    assert pending_transfer.get('role') == waiting_transfer.get(
        'role') == 'mediator'
    assert pending_transfer.get('payment_identifier') == '1'
    assert waiting_transfer.get('payment_identifier') == '2'
    assert pending_transfer.get('locked_amount') == str(locked_amount1)
    assert waiting_transfer.get('locked_amount') == str(locked_amount2)