Esempio n. 1
0
def test_next_route():
    amount = UNIT_TRANSFER_AMOUNT
    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel3 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
        channel3.identifier: channel3,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
        factories.route_from_channel(channel3),
    ]

    block_number = 10
    state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    msg = 'an initialized state must use the first valid route'
    assert state.initiator.channel_identifier == channel1.identifier, msg
    assert not state.cancelled_channels

    state_change = ActionCancelRoute(
        UNIT_REGISTRY_IDENTIFIER,
        channel1.identifier,
        available_routes,
    )
    iteration = initiator_manager.state_transition(
        state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    # HOP3 should be ignored because it doesnt have enough balance
    assert iteration.new_state.cancelled_channels == [channel1.identifier]
Esempio n. 2
0
def test_events_for_close_secret_unknown():
    """ Channel must not be closed when the unsafe region is reached and the
    secret is not known.
    """
    amount = 3
    block_number = 10
    expiration = block_number + 30
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
    )

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    state = TargetTransferState(from_route, from_transfer)

    events = target.events_for_close(state, from_channel, expiration)
    assert not events
Esempio n. 3
0
def test_init_with_maximum_pending_transfers_exceeded():
    channel1 = factories.make_channel(
        our_balance=2 * MAXIMUM_PENDING_TRANSFERS * UNIT_TRANSFER_AMOUNT,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel_map = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]
    pseudo_random_generator = random.Random()

    transitions = list()
    block_number = 1
    for _ in range(MAXIMUM_PENDING_TRANSFERS + 1):
        init_state_change = ActionInitInitiator(make_transfer_description(), available_routes)
        transitions.append(initiator_manager.state_transition(
            None,
            init_state_change,
            channel_map,
            pseudo_random_generator,
            block_number,
        ))

    failed_transition = transitions.pop()
    assert all(
        isinstance(transition.new_state, InitiatorPaymentState)
        for transition in transitions
    )

    assert failed_transition.new_state is None
    assert len(failed_transition.events) == 1
    assert isinstance(failed_transition.events[0], EventPaymentSentFailed)
Esempio n. 4
0
def make_from_route_from_counter(counter):
    from_channel = factories.make_channel(
        partner_balance=next(counter),
        partner_address=factories.HOP1,
        token_address=factories.make_address(),
        channel_identifier=next(counter),
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = factories.UNIT_REVEAL_TIMEOUT + 1

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                balance_proof=factories.BalanceProofProperties(
                    transferred_amount=0,
                    token_network_identifier=from_channel.token_network_identifier,
                ),
                amount=1,
                expiration=expiration,
                secret=sha3(factories.make_secret(next(counter))),
                initiator=factories.make_address(),
                target=factories.make_address(),
                payment_identifier=next(counter),
            ),
            sender=factories.HOP1,
            pkey=factories.HOP1_KEY,
        ),
    )
    return from_route, from_transfer
Esempio n. 5
0
def test_channel_settle_must_properly_cleanup():
    open_block_number = 10
    pseudo_random_generator = random.Random()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(our_balance=our_balance)

    channel_new_state_change = ContractReceiveChannelNew(token_network_id, channel_state)

    channel_new_iteration = token_network.state_transition(
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        token_network_id,
        channel_state.identifier,
        channel_state.partner_state.address,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        token_network_id,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert channel_state.identifier not in ids_to_channels
Esempio n. 6
0
def test_contract_receive_channelnew_must_be_idempotent():
    block_number = 10
    pseudo_random_generator = random.Random()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)
    payment_network_identifier = factories.make_payment_network_identifier()

    amount = 30
    our_balance = amount + 50
    channel_state1 = factories.make_channel(our_balance=our_balance)
    channel_state2 = copy.deepcopy(channel_state1)

    state_change1 = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_id,
        channel_state1,
        block_number,
    )

    token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        state_change1,
        pseudo_random_generator,
        block_number,
    )

    state_change2 = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_id,
        channel_state2,
        block_number + 1,
    )

    # replay the ContractReceiveChannelNew state change
    iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        state_change2,
        pseudo_random_generator,
        block_number,
    )

    msg = 'the channel must not have been overwritten'
    channelmap_by_id = iteration.new_state.channelidentifiers_to_channels
    assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg

    channelmap_by_address = iteration.new_state.partneraddresses_to_channelidentifiers
    partner_channels_ids = channelmap_by_address[channel_state1.partner_state.address]
    assert channel_state1.identifier in partner_channels_ids, msg
Esempio n. 7
0
def test_contract_receive_channelnew_must_be_idempotent():
    block_number = 10
    pseudo_random_generator = random.Random()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)

    amount = 30
    our_balance = amount + 50
    channel_state1 = factories.make_channel(our_balance=our_balance)
    channel_state2 = copy.deepcopy(channel_state1)

    state_change1 = ContractReceiveChannelNew(token_network_id, channel_state1)

    token_network.state_transition(
        token_network_state,
        state_change1,
        pseudo_random_generator,
        block_number,
    )

    # change the existing channel
    payment_identifier = 1
    message_identifier = random.randint(0, UINT64_MAX)
    channel.send_directtransfer(
        channel_state1,
        amount,
        message_identifier,
        payment_identifier,
    )

    state_change2 = ContractReceiveChannelNew(token_network_id, channel_state2)

    # replay the ContractReceiveChannelNew state change
    iteration = token_network.state_transition(
        token_network_state,
        state_change2,
        pseudo_random_generator,
        block_number,
    )

    msg = 'the channel must not been overwritten'
    channelmap_by_id = iteration.new_state.channelidentifiers_to_channels
    assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg

    channelmap_by_address = iteration.new_state.partneraddresses_to_channels
    assert channelmap_by_address[channel_state1.partner_state.address] == channel_state1, msg
Esempio n. 8
0
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    amount = 3
    block_number = 1
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    pseudo_random_generator = random.Random()

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = from_channel.reveal_timeout + block_number + 1
    from_transfer = factories.make_signed_transfer(
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
        channel_identifier=from_channel.identifier,
    )

    state_change = ActionInitTarget(
        from_route,
        from_transfer,
    )

    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )

    events = iteration.events
    assert events
    assert isinstance(events[0], SendSecretRequest)

    assert events[0].payment_identifier == from_transfer.payment_identifier
    assert events[0].amount == from_transfer.lock.amount
    assert events[0].secrethash == from_transfer.lock.secrethash
    assert events[0].recipient == initiator
Esempio n. 9
0
    def new_channel(self):
        """Create a new partner address with private key and channel. The
        private key and channels are listed in the instance's dictionaries,
        the address is returned and should be added to the partners Bundle.
        """

        partner_privkey, partner_address = factories.make_privkey_address()

        self.address_to_privkey[partner_address] = partner_privkey
        self.address_to_channel[partner_address] = factories.make_channel(
            our_balance=1000,
            partner_balance=1000,
            token_network_identifier=self.token_network_id,
            our_address=self.address,
            partner_address=partner_address,
        )

        return partner_address
Esempio n. 10
0
def netting_channel_state(chain_state, token_network_state, payment_network_state):
    partner = factories.make_address()
    channel_id = factories.make_channel_identifier()
    channel_state = factories.make_channel(
        our_balance=10,
        partner_balance=10,
        our_address=chain_state.our_address,
        partner_address=partner,
        token_address=token_network_state.token_address,
        payment_network_identifier=payment_network_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_id,
    )

    token_network_state.partneraddresses_to_channelidentifiers[partner].append(channel_id)
    token_network_state.channelidentifiers_to_channels[channel_id] = channel_state

    return channel_state
Esempio n. 11
0
def test_events_for_onchain_secretreveal():
    """ Secret must be registered on-chain when the unsafe region is reached and
    the secret is known.
    """
    amount = 3
    block_number = 10
    expiration = block_number + 30
    initiator = HOP1
    target_address = UNIT_TRANSFER_TARGET

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
    )

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    channel.register_secret(from_channel, UNIT_SECRET, UNIT_SECRETHASH)

    safe_to_wait = expiration - from_channel.reveal_timeout - 1
    unsafe_to_wait = expiration - from_channel.reveal_timeout

    state = TargetTransferState(from_route, from_transfer)
    events = target.events_for_onchain_secretreveal(state, from_channel, safe_to_wait)
    assert not events

    events = target.events_for_onchain_secretreveal(state, from_channel, unsafe_to_wait)
    assert events
    assert isinstance(events[0], ContractSendSecretReveal)
    assert events[0].secret == UNIT_SECRET
Esempio n. 12
0
def test_init_with_usable_routes():
    channel1 = factories.make_channel(
        our_balance=UNIT_TRANSFER_AMOUNT,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel_map = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]
    pseudo_random_generator = random.Random()

    init_state_change = ActionInitInitiator(
        factories.UNIT_TRANSFER_DESCRIPTION,
        available_routes,
    )

    block_number = 1
    transition = initiator_manager.state_transition(
        None,
        init_state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert isinstance(transition.new_state, InitiatorPaymentState)
    assert transition.events, 'we have a valid route, the mediated transfer event must be emitted'

    payment_state = transition.new_state
    assert payment_state.initiator.transfer_description == factories.UNIT_TRANSFER_DESCRIPTION

    mediated_transfers = [e for e in transition.events if isinstance(e, SendLockedTransfer)]
    assert len(mediated_transfers) == 1, 'mediated_transfer should /not/ split the transfer'

    send_mediated_transfer = mediated_transfers[0]
    transfer = send_mediated_transfer.transfer
    expiration = initiator.get_initial_lock_expiration(block_number, channel1.reveal_timeout)

    assert transfer.balance_proof.token_network_identifier == channel1.token_network_identifier
    assert transfer.lock.amount == factories.UNIT_TRANSFER_DESCRIPTION.amount
    assert transfer.lock.expiration == expiration
    assert transfer.lock.secrethash == factories.UNIT_TRANSFER_DESCRIPTION.secrethash
    assert send_mediated_transfer.recipient == channel1.partner_state.address
Esempio n. 13
0
def setup_initiator_tests(
        amount=UNIT_TRANSFER_AMOUNT,
        partner_balance=EMPTY,
        our_address=EMPTY,
        partner_address=EMPTY,
        block_number=1,
) -> InitiatorSetup:
    """Commonly used setup code for initiator manager and channel"""
    prng = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=partner_balance,
        our_address=our_address,
        partner_address=partner_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel_map = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]
    current_state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        prng,
        block_number,
    )

    lock = channel.get_lock(
        channel1.our_state,
        current_state.initiator.transfer_description.secrethash,
    )
    setup = InitiatorSetup(
        current_state=current_state,
        block_number=block_number,
        channel=channel1,
        channel_map=channel_map,
        available_routes=available_routes,
        prng=prng,
        lock=lock,
    )
    return setup
Esempio n. 14
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    amount = 3
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    pseudo_random_generator = random.Random()

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = from_channel.reveal_timeout + block_number + 1
    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
    )

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    state_change = ActionInitTarget(from_route, from_transfer)
    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
Esempio n. 15
0
def make_target_state(our_address, amount, block_number, initiator, expiration=None):
    from_channel = factories.make_channel(
        our_address=our_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    if expiration is None:
        expiration = from_channel.reveal_timeout + block_number + 1

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    state = TargetTransferState(from_route, from_transfer)

    return from_channel, state
Esempio n. 16
0
def test_routing_issue2663(
    chain_state,
    payment_network_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    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,
        block_hash=open_block_number_hash,
    )
    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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=open_block_number_hash,
    )

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

    # 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 == address1

    # 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[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,
    }

    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 == address1

    # 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 == 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[0].node_address == address1
Esempio n. 17
0
def test_routing_updates(
    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()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address1,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    open_block_hash = factories.make_block_hash()
    # create a new channel as participant, check graph update
    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    graph_state = channel_new_iteration1.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[our_address][address1] is not None
    assert len(graph_state.network.edges()) == 1

    # create a new channel without being participant, check graph update
    new_channel_identifier = factories.make_channel_identifier()
    channel_new_state_change = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert graph_state.network[our_address][address1] is not None
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 2

    # close the channel the node is a participant of, check edge is removed from graph
    closed_block_number = open_block_number + 20
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change1 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_close_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    # Check that a second ContractReceiveChannelClosed events is handled properly
    # This might have been sent from the other participant of the channel
    # See issue #2449
    channel_close_state_change2 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.our_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration1.new_state,
        state_change=channel_close_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    graph_state = channel_closed_iteration2.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 1

    # close the channel the node is not a participant of, check edge is removed from graph
    channel_close_state_change3 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration2.new_state,
        state_change=channel_close_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
        block_hash=factories.make_block_hash(),
    )

    # Check that a second ContractReceiveRouteClosed events is handled properly.
    # This might have been sent from the second participant of the channel
    # See issue #2449
    closed_block_plus_10_hash = factories.make_block_hash()
    channel_close_state_change4 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number + 10,
        block_hash=closed_block_plus_10_hash,
    )

    channel_closed_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration3.new_state,
        state_change=channel_close_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
        block_hash=closed_block_plus_10_hash,
    )

    graph_state = channel_closed_iteration4.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier not in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 0
    assert len(graph_state.network.edges()) == 0
Esempio n. 18
0
def test_multiple_channel_states(
    chain_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    open_block_hash = factories.make_block_hash()
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_route,
        mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    # Create new channel while the previous one is pending unlock
    new_channel_state = factories.make_channel(
        our_balance=our_balance,
        partner_balance=our_balance,
        partner_address=address,
    )
    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=new_channel_state,
        block_number=closed_block_number + 1,
        block_hash=factories.make_block_hash(),
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    token_network_state_after_new_open = channel_new_iteration.new_state
    ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels

    assert len(ids_to_channels) == 2
    assert channel_state.identifier in ids_to_channels
Esempio n. 19
0
def test_contract_receive_channelnew_must_be_idempotent():
    block_number = 10
    pseudo_random_generator = random.Random()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)
    payment_network_identifier = factories.make_payment_network_identifier()

    amount = 30
    our_balance = amount + 50
    channel_state1 = factories.make_channel(our_balance=our_balance)
    channel_state2 = copy.deepcopy(channel_state1)

    state_change1 = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_id,
        channel_state1,
        block_number,
    )

    token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        state_change1,
        pseudo_random_generator,
        block_number,
    )

    # change the existing channel
    payment_identifier = 1
    message_identifier = random.randint(0, UINT64_MAX)
    channel.send_directtransfer(
        channel_state1,
        amount,
        message_identifier,
        payment_identifier,
    )

    state_change2 = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_id,
        channel_state2,
        block_number + 1,
    )

    # replay the ContractReceiveChannelNew state change
    iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        state_change2,
        pseudo_random_generator,
        block_number,
    )

    msg = 'the channel must not been overwritten'
    channelmap_by_id = iteration.new_state.channelidentifiers_to_channels
    assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg

    channelmap_by_address = iteration.new_state.partneraddresses_to_channelidentifiers
    partner_channels_ids = channelmap_by_address[
        channel_state1.partner_state.address]
    assert channel_state1.identifier in partner_channels_ids, msg
Esempio n. 20
0
def test_multiple_channel_states(
        chain_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
        open_block_number,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_route,
        mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    # Create new channel while the previous one is pending unlock
    new_channel_state = factories.make_channel(
        our_balance=our_balance,
        partner_balance=our_balance,
        partner_address=address,
    )
    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        new_channel_state,
        closed_block_number + 1,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    token_network_state_after_new_open = channel_new_iteration.new_state
    ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels

    assert len(ids_to_channels) == 2
    assert channel_state.identifier in ids_to_channels
Esempio n. 21
0
def create_square_network_topology(
        payment_network_state,
        token_network_state,
        our_address,
) -> typing.Tuple[
    TokenNetworkState,
    typing.List[typing.Address],
    typing.List[NettingChannelState],
]:
    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

    return (
        channel_new_iteration4.new_state,
        [address1, address2, address3],
        (channel_state1, channel_state2),
    )
Esempio n. 22
0
def test_initiator_lock_expired():
    amount = UNIT_TRANSFER_AMOUNT * 2
    block_number = 1
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    # Trigger lock expiry
    state_change = Block(
        block_number=transfer.lock.expiration +
        DEFAULT_NUMBER_OF_CONFIRMATIONS_BLOCK,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert events.must_contain_entry(
        iteration.events, SendLockExpired, {
            'balance_proof': {
                'nonce': 2,
                'transferred_amount': 0,
                'locked_amount': 0,
            },
            'secrethash': transfer.lock.secrethash,
            'recipient': channel1.partner_state.address,
        })

    assert transfer.lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks

    # Create 2 other transfers
    transfer2_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer2'),
        channel_map,
        pseudo_random_generator,
        30,
    )
    transfer2_lock = transfer2_state.initiator.transfer.lock

    transfer3_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer3'),
        channel_map,
        pseudo_random_generator,
        32,
    )

    transfer3_lock = transfer3_state.initiator.transfer.lock

    assert len(channel1.our_state.secrethashes_to_lockedlocks) == 2

    assert transfer2_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    expiration_block_number = transfer2_lock.expiration + DEFAULT_NUMBER_OF_CONFIRMATIONS_BLOCK

    block = Block(
        block_number=expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        transfer2_state,
        block,
        channel_map,
        pseudo_random_generator,
        expiration_block_number,
    )

    # Transfer 2 expired
    assert transfer2_lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks

    # Transfer 3 is still there
    assert transfer3_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks
Esempio n. 23
0
def test_refund_transfer_next_route():
    amount = UNIT_TRANSFER_AMOUNT
    our_address = factories.ADDR
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=amount,
        our_address=our_address,
        partner_address=refund_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel3 = factories.make_channel(
        our_balance=amount,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
        channel3.identifier: channel3,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
        factories.route_from_channel(channel3),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    original_transfer = current_state.initiator.transfer

    refund_transfer = factories.make_signed_transfer(
        amount,
        our_address,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=channel1.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )
    assert channel1.partner_state.address == refund_address

    state_change = ReceiveTransferRefundCancelRoute(
        routes=available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )
    assert iteration.new_state is not None

    route_cancelled = next(e for e in iteration.events if isinstance(e, EventUnlockFailed))
    new_transfer = next(e for e in iteration.events if isinstance(e, SendLockedTransfer))

    assert route_cancelled, 'The previous transfer must be cancelled'
    assert new_transfer, 'No mediated transfer event emitted, should have tried a new route'
    msg = 'the new transfer must use a new secret / secrethash'
    assert new_transfer.transfer.lock.secrethash != refund_transfer.lock.secrethash, msg
    assert iteration.new_state.initiator is not None
Esempio n. 24
0
def test_payer_enter_danger_zone_with_transfer_payed():
    """ A mediator may have paid the next hop (payee), and didn't get paid by
    the previous hop (payer).

    When this happens, an assertion must not be hit, because it means the
    transfer must be withdrawn on-chain.

    Issue: https://github.com/raiden-network/raiden/issues/1013
    """
    amount = 10
    block_number = 5
    target = HOP2
    expiration = 30

    payer_channel = factories.make_channel(
        partner_balance=amount,
        partner_address=UNIT_TRANSFER_SENDER,
        token_address=UNIT_TOKEN_ADDRESS,
    )

    payer_transfer = factories.make_signed_transfer_for(
        payer_channel,
        amount,
        HOP1,
        target,
        expiration,
        UNIT_SECRET,
    )

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
    )
    channelmap = {
        channel1.identifier: channel1,
        payer_channel.identifier: payer_channel,
    }
    possible_routes = [factories.route_from_channel(channel1)]

    mediator_state = MediatorTransferState(UNIT_HASHLOCK)
    initial_iteration = mediator.mediate_transfer(
        mediator_state,
        possible_routes,
        payer_channel,
        channelmap,
        payer_transfer,
        block_number,
    )

    send_transfer = must_contain_entry(initial_iteration.events,
                                       SendMediatedTransfer, {})
    assert send_transfer

    lock_expiration = send_transfer.transfer.lock.expiration

    new_state = initial_iteration.new_state
    for block_number in range(block_number, lock_expiration + 1):
        block_state_change = Block(block_number)

        block_iteration = mediator.handle_block(
            channelmap,
            new_state,
            block_state_change,
            block_number,
        )
        new_state = block_iteration.new_state

    # send the balance proof, transitioning the payee state to paid
    assert new_state.transfers_pair[0].payee_state == 'payee_pending'
    receive_secret = ReceiveSecretReveal(
        UNIT_SECRET,
        channel1.partner_state.address,
    )
    paid_iteration = mediator.state_transition(
        new_state,
        receive_secret,
        channelmap,
        block_number,
    )
    paid_state = paid_iteration.new_state
    assert paid_state.transfers_pair[0].payee_state == 'payee_balance_proof'

    # move to the block in which the payee lock expires. This must not raise an
    # assertion
    expired_block_number = lock_expiration + 1
    expired_block_state_change = Block(expired_block_number)
    block_iteration = mediator.handle_block(
        channelmap,
        paid_state,
        expired_block_state_change,
        expired_block_number,
    )
Esempio n. 25
0
def test_channel_settle_must_properly_cleanup():
    open_block_number = 10
    open_block_hash = factories.make_block_hash()
    pseudo_random_generator = random.Random()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)
    payment_network_identifier = factories.make_payment_network_identifier()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(our_balance=our_balance)

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_id,
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_id,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_id,
        channel_identifier=channel_state.identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert channel_state.identifier not in ids_to_channels
Esempio n. 26
0
def test_target_receive_lock_expired():
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        lock_amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    init = ActionInitTarget(
        from_route,
        from_transfer,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is not None
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

    balance_proof = factories.make_signed_balance_proof(
        2,
        from_transfer.balance_proof.transferred_amount,
        0,
        from_transfer.balance_proof.token_network_identifier,
        from_channel.identifier,
        EMPTY_MERKLE_ROOT,
        from_transfer.lock.secrethash,
        sender_address=UNIT_TRANSFER_SENDER,
        private_key=UNIT_TRANSFER_PKEY,
    )

    lock_expired_state_change = ReceiveLockExpired(
        HOP1,
        balance_proof,
        from_transfer.lock.secrethash,
        1,
    )

    iteration = target.state_transition(
        init_transition.new_state,
        lock_expired_state_change,
        from_channel,
        pseudo_random_generator,
        10,
    )

    assert must_contain_entry(iteration.events, SendProcessed, {})
    assert iteration.new_state is None
Esempio n. 27
0
def test_regression_mediator_task_no_routes():
    """ The mediator must only be cleared after the waiting transfer's lock has
    been handled.

    If a node receives a transfer to mediate, but there is no route available
    (because there is no sufficient capacity or the partner nodes are offline),
    and a refund is not possible, the mediator task must not be cleared,
    otherwise followup remove expired lock messages wont be processed and the
    nodes will get out of sync.
    """

    amount = 10
    block_number = 5
    target = HOP2
    expiration = 30
    pseudo_random_generator = random.Random()

    payer_channel = factories.make_channel(
        partner_balance=amount,
        partner_address=HOP2,
        token_address=UNIT_TOKEN_ADDRESS,
    )
    payer_route = factories.route_from_channel(payer_channel)

    payer_transfer = factories.make_signed_transfer_for(
        payer_channel,
        amount,
        HOP1,
        target,
        expiration,
        UNIT_SECRET,
        pkey=HOP2_KEY,
        sender=HOP2,
    )

    available_routes = []
    channel_map = {
        payer_channel.identifier: payer_channel,
    }

    init_state_change = ActionInitMediator(
        available_routes,
        payer_route,
        payer_transfer,
    )
    initial_state = None
    init_iteration = mediator.state_transition(
        initial_state,
        init_state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )
    msg = 'The task must not be cleared, even if there is no route to forward the transfer'
    assert init_iteration.new_state is not None, msg
    assert init_iteration.new_state.waiting_transfer.transfer == payer_transfer
    assert must_contain_entry(init_iteration.events, SendLockedTransfer,
                              {}) is None
    assert must_contain_entry(init_iteration.events, SendRefundTransfer,
                              {}) is None

    secrethash = UNIT_SECRETHASH
    lock = payer_channel.partner_state.secrethashes_to_lockedlocks[secrethash]

    # Creates a transfer as it was from the *partner*
    send_lock_expired, _ = channel.create_sendexpiredlock(
        sender_end_state=payer_channel.partner_state,
        locked_lock=lock,
        pseudo_random_generator=pseudo_random_generator,
        chain_id=payer_channel.chain_id,
        token_network_identifier=payer_channel.token_network_identifier,
        channel_identifier=payer_channel.identifier,
        recipient=payer_channel.our_state.address,
    )
    assert send_lock_expired
    lock_expired_message = message_from_sendevent(send_lock_expired, HOP1)
    lock_expired_message.sign(HOP2_KEY)
    balance_proof = balanceproof_from_envelope(lock_expired_message)

    message_identifier = message_identifier_from_prng(pseudo_random_generator)
    expired_block_number = lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2

    # Regression: The mediator must still be able to process the block which
    # expires the lock
    expire_block_iteration = mediator.state_transition(
        init_iteration.new_state,
        Block(
            block_number=expired_block_number,
            gas_limit=0,
            block_hash=None,
        ),
        channel_map,
        pseudo_random_generator,
        expired_block_number,
    )
    assert expire_block_iteration.new_state is not None

    receive_expired_iteration = mediator.state_transition(
        expire_block_iteration.new_state,
        ReceiveLockExpired(
            balance_proof=balance_proof,
            secrethash=secrethash,
            message_identifier=message_identifier,
        ),
        channel_map,
        pseudo_random_generator,
        expired_block_number,
    )

    msg = 'The only used channel had the lock cleared, the task must be cleared'
    assert receive_expired_iteration.new_state is None, msg
    assert secrethash not in payer_channel.partner_state.secrethashes_to_lockedlocks
Esempio n. 28
0
def test_regression_mediator_send_lock_expired_with_new_block():
    """ The mediator must send the lock expired, but it must **not** clear
    itself if it has not **received** the corresponding message.
    """
    amount = 10
    block_number = 5
    target = HOP2
    expiration = 30
    pseudo_random_generator = random.Random()

    payer_channel = factories.make_channel(
        partner_balance=amount,
        partner_address=UNIT_TRANSFER_SENDER,
        token_address=UNIT_TOKEN_ADDRESS,
    )
    payer_route = factories.route_from_channel(payer_channel)

    payer_transfer = factories.make_signed_transfer_for(
        payer_channel,
        amount,
        HOP1,
        target,
        expiration,
        UNIT_SECRET,
    )

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
    )
    available_routes = [factories.route_from_channel(channel1)]
    channel_map = {
        channel1.identifier: channel1,
        payer_channel.identifier: payer_channel,
    }

    init_state_change = ActionInitMediator(
        available_routes,
        payer_route,
        payer_transfer,
    )
    initial_state = None
    init_iteration = mediator.state_transition(
        initial_state,
        init_state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )
    assert init_iteration.new_state is not None
    send_transfer = must_contain_entry(init_iteration.events,
                                       SendLockedTransfer, {})
    assert send_transfer

    transfer = send_transfer.transfer

    block_expiration_number = transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2
    block = Block(
        block_number=block_expiration_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = mediator.state_transition(
        init_iteration.new_state,
        block,
        channel_map,
        pseudo_random_generator,
        block_expiration_number,
    )

    msg = ("The payer's lock has also expired, "
           "but it must not be removed locally (without an Expired lock)")
    assert transfer.lock.secrethash in payer_channel.partner_state.secrethashes_to_lockedlocks, msg

    msg = 'The payer has not yet sent an expired lock, the task can not be cleared yet'
    assert iteration.new_state is not None, msg

    assert must_contain_entry(iteration.events, SendLockExpired, {
        'secrethash': transfer.lock.secrethash,
    })
    assert transfer.lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks
Esempio n. 29
0
def test_channel_data_removed_after_unlock(
    chain_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
        open_block_number,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_route,
        mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    unlock_blocknumber = settle_block_number + 5
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        participant=our_address,
        partner=address,
        locksroot=lock_secrethash,
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=closed_block_number + 1,
    )
    channel_unlock_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_settled_iteration.new_state,
        channel_batch_unlock_state_change,
        pseudo_random_generator,
        unlock_blocknumber,
    )

    token_network_state_after_unlock = channel_unlock_iteration.new_state
    ids_to_channels = token_network_state_after_unlock.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0
Esempio n. 30
0
def test_initiator_lock_expired():
    amount = UNIT_TRANSFER_AMOUNT * 2

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
    ]

    block_number = 10
    transfer_description = factories.make_transfer_description(
        secret=UNIT_SECRET,
        payment_network_identifier=channel1.payment_network_identifier,
    )
    current_state = make_initiator_manager_state(
        available_routes,
        transfer_description,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    # Trigger lock expiry
    state_change = Block(
        block_number=transfer.lock.expiration +
        DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert events.must_contain_entry(
        iteration.events, SendLockExpired, {
            'balance_proof': {
                'nonce': 2,
                'transferred_amount': 0,
                'locked_amount': 0,
            },
            'secrethash': transfer.lock.secrethash,
            'recipient': channel1.partner_state.address,
        })
    # Since the lock expired make sure we also get the payment sent failed event
    assert events.must_contain_entry(
        iteration.events, EventPaymentSentFailed, {
            'payment_network_identifier': channel1.payment_network_identifier,
            'token_network_identifier': channel1.token_network_identifier,
            'identifier': UNIT_TRANSFER_IDENTIFIER,
            'target': transfer.target,
            'reason': "transfer's lock has expired",
        })

    assert transfer.lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks
    msg = 'the initiator payment task must be deleted at block of the lock expiration'
    assert not iteration.new_state, msg

    # Create 2 other transfers
    transfer2_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer2'),
        channel_map,
        pseudo_random_generator,
        30,
    )
    transfer2_lock = transfer2_state.initiator.transfer.lock

    transfer3_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer3'),
        channel_map,
        pseudo_random_generator,
        32,
    )

    transfer3_lock = transfer3_state.initiator.transfer.lock

    assert len(channel1.our_state.secrethashes_to_lockedlocks) == 2

    assert transfer2_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    expiration_block_number = transfer2_lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2

    block = Block(
        block_number=expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        transfer2_state,
        block,
        channel_map,
        pseudo_random_generator,
        expiration_block_number,
    )

    # Transfer 2 expired
    assert transfer2_lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks

    # Transfer 3 is still there
    assert transfer3_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks
Esempio n. 31
0
def test_routing_priority(
    chain_state,
    payment_network_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    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,
        block_hash=open_block_number_hash,
    )
    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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=open_block_number_hash,
    )

    # 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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=factories.make_block_hash(),
    )

    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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=factories.make_block_hash(),
    )

    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,
        block_hash=open_block_number_hash,
    )

    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,
        block_hash=factories.make_block_hash(),
    )

    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,
        block_hash=open_block_number_hash,
    )

    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,
        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,
        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
Esempio n. 32
0
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
Esempio n. 33
0
def test_initiator_lock_expired():
    amount = UNIT_TRANSFER_AMOUNT * 2

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
    ]

    block_number = 10
    transfer_description = factories.make_transfer_description(
        secret=UNIT_SECRET,
        payment_network_identifier=channel1.payment_network_identifier,
    )
    current_state = make_initiator_manager_state(
        available_routes,
        transfer_description,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    # Trigger lock expiry
    state_change = Block(
        block_number=channel.get_sender_expiration_threshold(transfer.lock),
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert events.must_contain_entry(iteration.events, SendLockExpired, {
        'balance_proof': {
            'nonce': 2,
            'transferred_amount': 0,
            'locked_amount': 0,
        },
        'secrethash': transfer.lock.secrethash,
        'recipient': channel1.partner_state.address,
    })
    # Since the lock expired make sure we also get the payment sent failed event
    assert events.must_contain_entry(iteration.events, EventPaymentSentFailed, {
        'payment_network_identifier': channel1.payment_network_identifier,
        'token_network_identifier': channel1.token_network_identifier,
        'identifier': UNIT_TRANSFER_IDENTIFIER,
        'target': transfer.target,
        'reason': "transfer's lock has expired",
    })

    assert transfer.lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks
    msg = 'the initiator payment task must be deleted at block of the lock expiration'
    assert not iteration.new_state, msg

    # Create 2 other transfers
    transfer2_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer2'),
        channel_map,
        pseudo_random_generator,
        30,
    )
    transfer2_lock = transfer2_state.initiator.transfer.lock

    transfer3_state = make_initiator_manager_state(
        available_routes,
        make_transfer_description('transfer3'),
        channel_map,
        pseudo_random_generator,
        32,
    )

    transfer3_lock = transfer3_state.initiator.transfer.lock

    assert len(channel1.our_state.secrethashes_to_lockedlocks) == 2

    assert transfer2_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    expiration_block_number = channel.get_sender_expiration_threshold(transfer2_lock)

    block = Block(
        block_number=expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        transfer2_state,
        block,
        channel_map,
        pseudo_random_generator,
        expiration_block_number,
    )

    # Transfer 2 expired
    assert transfer2_lock.secrethash not in channel1.our_state.secrethashes_to_lockedlocks

    # Transfer 3 is still there
    assert transfer3_lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks
Esempio n. 34
0
def test_state_wait_secretrequest_invalid_amount_and_sender():
    amount = UNIT_TRANSFER_AMOUNT
    block_number = 1
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel_map = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]
    current_state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    lock = channel.get_lock(
        channel1.our_state,
        current_state.initiator.transfer_description.secrethash,
    )

    state_change = ReceiveSecretRequest(
        UNIT_TRANSFER_IDENTIFIER,
        lock.amount + 1,
        lock.expiration,
        lock.secrethash,
        UNIT_TRANSFER_INITIATOR,
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert len(iteration.events) == 0
    assert iteration.new_state.initiator.received_secret_request is False

    # Now the proper target sends the message, this should be applied
    state_change_2 = ReceiveSecretRequest(
        UNIT_TRANSFER_IDENTIFIER,
        lock.amount,
        lock.expiration,
        lock.secrethash,
        UNIT_TRANSFER_TARGET,
    )

    iteration2 = initiator_manager.state_transition(
        iteration.new_state,
        state_change_2,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    assert iteration2.new_state.initiator.received_secret_request is True
    assert isinstance(iteration2.events[0], SendSecretReveal)
Esempio n. 35
0
def test_refund_transfer_no_more_routes():
    amount = UNIT_TRANSFER_AMOUNT
    block_number = 1
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=amount,
        our_address=UNIT_TRANSFER_INITIATOR,
        partner_address=refund_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channelmap = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]

    current_state = make_initiator_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channelmap,
        pseudo_random_generator,
        block_number,
    )

    original_transfer = current_state.initiator.transfer
    channel_identifier = current_state.initiator.channel_identifier
    channel_state = channelmap[channel_identifier]

    refund_transfer = factories.make_signed_transfer(
        amount,
        original_transfer.initiator,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=channel1.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )

    state_change = ReceiveTransferRefundCancelRoute(
        sender=channel_state.partner_state.address,
        routes=available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channelmap,
        pseudo_random_generator,
        block_number,
    )
    assert iteration.new_state is None

    unlocked_failed = next(e for e in iteration.events
                           if isinstance(e, EventUnlockFailed))
    sent_failed = next(e for e in iteration.events
                       if isinstance(e, EventPaymentSentFailed))

    assert unlocked_failed
    assert sent_failed
Esempio n. 36
0
def test_state_transition():
    """ Happy case testing. """
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    payment_network_identifier = factories.make_address()
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        lock_amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    init = ActionInitTarget(
        payment_network_identifier,
        from_route,
        from_transfer,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is not None
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

    first_new_block = Block(block_number + 1)
    first_block_iteration = target.state_transition(
        init_transition.new_state,
        first_new_block,
        from_channel,
        pseudo_random_generator,
        first_new_block.block_number,
    )

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        first_block_iteration.new_state,
        secret_reveal,
        from_channel,
        pseudo_random_generator,
        first_new_block,
    )
    assert reveal_iteration.events

    second_new_block = Block(block_number + 2)
    iteration = target.state_transition(
        init_transition.new_state,
        second_new_block,
        from_channel,
        pseudo_random_generator,
        second_new_block.block_number,
    )
    assert not iteration.events

    nonce = from_transfer.balance_proof.nonce + 1
    transferred_amount = lock_amount
    locksroot = EMPTY_MERKLE_ROOT
    invalid_message_hash = b'\x00' * 32
    locked_amount = 0

    balance_proof = factories.make_signed_balance_proof(
        nonce,
        transferred_amount,
        locked_amount,
        from_route.channel_identifier,
        locksroot,
        invalid_message_hash,
        UNIT_TRANSFER_PKEY,
        UNIT_TRANSFER_SENDER,
    )

    payment_network_identifier = factories.make_address()
    balance_proof_state_change = ReceiveUnlock(
        random.randint(0, UINT64_MAX),
        UNIT_SECRET,
        balance_proof,
    )

    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
        from_channel,
        pseudo_random_generator,
        block_number + 2,
    )
    assert proof_iteration.new_state is None
Esempio n. 37
0
def test_state_transition():
    """ Happy case testing. """
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        lock_amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    init = ActionInitTarget(
        from_route,
        from_transfer,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is not None
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

    first_new_block = Block(block_number + 1)
    first_block_iteration = target.state_transition(
        init_transition.new_state,
        first_new_block,
        from_channel,
        pseudo_random_generator,
        first_new_block.block_number,
    )

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        first_block_iteration.new_state,
        secret_reveal,
        from_channel,
        pseudo_random_generator,
        first_new_block,
    )
    assert reveal_iteration.events

    second_new_block = Block(block_number + 2)
    iteration = target.state_transition(
        init_transition.new_state,
        second_new_block,
        from_channel,
        pseudo_random_generator,
        second_new_block.block_number,
    )
    assert not iteration.events

    nonce = from_transfer.balance_proof.nonce + 1
    transferred_amount = lock_amount
    locksroot = EMPTY_MERKLE_ROOT
    invalid_message_hash = b'\x00' * 32
    locked_amount = 0

    balance_proof = factories.make_signed_balance_proof(
        nonce,
        transferred_amount,
        locked_amount,
        from_channel.token_network_identifier,
        from_route.channel_identifier,
        locksroot,
        invalid_message_hash,
        UNIT_TRANSFER_PKEY,
        UNIT_TRANSFER_SENDER,
    )

    balance_proof_state_change = ReceiveUnlock(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
        balance_proof=balance_proof,
    )

    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
        from_channel,
        pseudo_random_generator,
        block_number + 2,
    )
    assert proof_iteration.new_state is None
def create_square_network_topology(
        payment_network_state,
        token_network_state,
        our_address,
) -> typing.Tuple[
    TokenNetworkState,
    typing.List[typing.Address],
    typing.List[NettingChannelState],
]:
    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

    return (
        channel_new_iteration4.new_state,
        [address1, address2, address3],
        (channel_state1, channel_state2),
    )
Esempio n. 39
0
def test_mediator_clear_pairs_after_batch_unlock(
        chain_state,
        token_network_state,
        our_address,
):
    """ Regression test for https://github.com/raiden-network/raiden/issues/2932
    The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where
    he is a participant is received.
    """
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
        open_block_number,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_mediator = ActionInitMediator(
        routes=[from_route],
        from_route=from_route,
        from_transfer=mediated_transfer,
    )

    node.state_transition(chain_state, init_mediator)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    block_number = closed_block_number + 1
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        participant=our_address,
        partner=address,
        locksroot=lock_secrethash,
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=block_number,
    )
    channel_unlock_iteration = node.state_transition(
        chain_state=chain_state,
        state_change=channel_batch_unlock_state_change,
    )
    chain_state = channel_unlock_iteration.new_state
    token_network_state = views.get_token_network_by_identifier(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
    )
    ids_to_channels = token_network_state.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0

    # Make sure that all is fine in the next block
    block = Block(
        block_number=block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = node.state_transition(
        chain_state=chain_state,
        state_change=block,
    )
    assert iteration.new_state

    # Make sure that mediator task was cleared during the next block processing
    # since the channel was removed
    mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(lock_secrethash)
    assert not mediator_task
Esempio n. 40
0
def test_mediator_clear_pairs_after_batch_unlock(
    chain_state,
    token_network_state,
    our_address,
):
    """ Regression test for https://github.com/raiden-network/raiden/issues/2932
    The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where
    he is a participant is received.
    """
    open_block_number = 10
    open_block_hash = factories.make_block_hash()
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_mediator = ActionInitMediator(
        routes=[from_route],
        from_route=from_route,
        from_transfer=mediated_transfer,
    )

    node.state_transition(chain_state, init_mediator)

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    block_number = closed_block_number + 1
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        participant=our_address,
        partner=address,
        locksroot=lock_secrethash,
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=block_number,
        block_hash=factories.make_block_hash(),
    )
    channel_unlock_iteration = node.state_transition(
        chain_state=chain_state,
        state_change=channel_batch_unlock_state_change,
    )
    chain_state = channel_unlock_iteration.new_state
    token_network_state = views.get_token_network_by_identifier(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
    )
    ids_to_channels = token_network_state.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0

    # Make sure that all is fine in the next block
    block = Block(
        block_number=block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = node.state_transition(
        chain_state=chain_state,
        state_change=block,
    )
    assert iteration.new_state

    # Make sure that mediator task was cleared during the next block processing
    # since the channel was removed
    mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(
        lock_secrethash)
    assert not mediator_task
Esempio n. 41
0
def test_routing_updates(
        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()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address1,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    # create a new channel as participant, check graph update
    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration1.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[our_address][address1] is not None
    assert len(graph_state.network.edges()) == 1

    # create a new channel without being participant, check graph update
    new_channel_identifier = factories.make_channel_identifier()
    channel_new_state_change = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert graph_state.network[our_address][address1] is not None
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 2

    # close the channel the node is a participant of, check edge is removed from graph
    closed_block_number = open_block_number + 20
    channel_close_state_change1 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_close_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
    )

    # Check that a second ContractReceiveChannelClosed events is handled properly
    # This might have been sent from the other participant of the channel
    # See issue #2449
    channel_close_state_change2 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.our_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration1.new_state,
        state_change=channel_close_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
    )

    graph_state = channel_closed_iteration2.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 1

    # close the channel the node is not a participant of, check edge is removed from graph
    channel_close_state_change3 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration2.new_state,
        state_change=channel_close_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
    )

    # Check that a second ContractReceiveRouteClosed events is handled properly.
    # This might have been sent from the second participant of the channel
    # See issue #2449
    channel_close_state_change4 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number + 10,
    )

    channel_closed_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration3.new_state,
        state_change=channel_close_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
    )

    graph_state = channel_closed_iteration4.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier not in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 0
    assert len(graph_state.network.edges()) == 0
Esempio n. 42
0
def test_channel_settle_must_properly_cleanup():
    open_block_number = 10
    open_block_hash = factories.make_block_hash()

    token_network_id = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(token_network_id, token_id)

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(our_balance=our_balance)

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    channel_new_iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        block_number=open_block_number,
        block_hash=open_block_hash,
    )

    closed_block_number = open_block_number + 10
    closed_block_hash = factories.make_block_hash()
    channel_close_state_change = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        canonical_identifier=channel_state.canonical_identifier,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    channel_closed_iteration = token_network.state_transition(
        token_network_state=channel_new_iteration.new_state,
        state_change=channel_close_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=channel_state.canonical_identifier,
        block_number=settle_block_number,
        block_hash=factories.make_block_hash(),
        our_onchain_locksroot=EMPTY_MERKLE_ROOT,
        partner_onchain_locksroot=EMPTY_MERKLE_ROOT,
    )

    channel_settled_iteration = token_network.state_transition(
        token_network_state=channel_closed_iteration.new_state,
        state_change=channel_settled_state_change,
        block_number=closed_block_number,
        block_hash=closed_block_hash,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert channel_state.identifier not in ids_to_channels
Esempio n. 43
0
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
Esempio n. 44
0
def test_refund_transfer_next_route():
    amount = UNIT_TRANSFER_AMOUNT
    our_address = factories.ADDR
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=amount,
        our_address=our_address,
        partner_address=refund_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel3 = factories.make_channel(
        our_balance=amount,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )

    channelmap = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
        channel3.identifier: channel3,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
        factories.route_from_channel(channel3),
    ]

    block_number = 10
    current_state = make_initiator_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channelmap,
        pseudo_random_generator,
        block_number,
    )

    original_transfer = current_state.initiator.transfer
    channel_identifier = current_state.initiator.channel_identifier
    channel_state = channelmap[channel_identifier]

    refund_transfer = factories.make_signed_transfer(
        amount,
        our_address,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=channel1.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )
    assert channel_state.partner_state.address == refund_address

    state_change = ReceiveTransferRefundCancelRoute(
        sender=refund_address,
        routes=available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channelmap,
        pseudo_random_generator,
        block_number,
    )
    assert iteration.new_state is not None

    route_cancelled = next(e for e in iteration.events
                           if isinstance(e, EventUnlockFailed))
    new_transfer = next(e for e in iteration.events
                        if isinstance(e, SendLockedTransfer))

    assert route_cancelled, 'The previous transfer must be cancelled'
    assert new_transfer, 'No mediated transfer event emitted, should have tried a new route'
    msg = 'the new transfer must use a new secret / secrethash'
    assert new_transfer.transfer.lock.secrethash != refund_transfer.lock.secrethash, msg
    assert iteration.new_state.initiator is not None