Example #1
0
def test_fullnetwork(raiden_chain):
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking

    token_address = app0.raiden.chain.default_registry.token_addresses()[0]

    amount = 80
    random.seed(0)
    direct_transfer(app0, app1, token_address, amount)
    # Assert default identifier is generated correctly
    fchannel = channel(app0, app1, token_address)
    last_transfer = get_sent_transfer(fchannel, 0)
    random.seed(0)
    assert_identifier_correct(app0, token_address, app1.raiden.address,
                              last_transfer.identifier)

    amount = 50
    direct_transfer(app1, app2, token_address, amount)

    amount = 30
    random.seed(0)
    mediated_transfer(app1, app2, token_address, amount)
    # Assert default identifier is generated correctly
    fchannel = channel(app1, app2, token_address)
    last_transfer = get_sent_transfer(fchannel, 1)
    random.seed(0)
    assert_identifier_correct(app1, token_address, app2.raiden.address,
                              last_transfer.identifier)
Example #2
0
def test_fullnetwork(raiden_chain):
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking

    asset_address = app0.raiden.chain.default_registry.asset_addresses()[0]

    amount = 80
    random.seed(0)
    direct_transfer(app0, app1, asset_address, amount)
    # Assert default identifier is generated correctly
    fchannel = channel(app0, app1, asset_address)
    last_transfer = get_sent_transfer(fchannel, 0)
    random.seed(0)
    assert_identifier_correct(app0, asset_address, app1.raiden.address, last_transfer.identifier)

    amount = 50
    direct_transfer(app1, app2, asset_address, amount)

    amount = 30
    random.seed(0)
    mediated_transfer(
        app1,
        app2,
        asset_address,
        amount
    )
    # Assert default identifier is generated correctly
    fchannel = channel(app1, app2, asset_address)
    last_transfer = get_sent_transfer(fchannel, 1)
    random.seed(0)
    assert_identifier_correct(app1, asset_address, app2.raiden.address, last_transfer.identifier)
Example #3
0
def test_fullnetwork(raiden_chain):
    app0, app1, app2, app3 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = app0.raiden.chain.default_registry.token_addresses()[0]
    channel_0_1 = channel(app0, app1, token_address)
    channel_1_2 = channel(app1, app2, token_address)
    channel_3_2 = channel(app3, app2, token_address)
    channel_0_3 = channel(app0, app3, token_address)

    amount = 80
    direct_transfer(app0, app1, token_address, amount)
    last_transfer = get_sent_transfer(channel_0_1, 0)
    assert last_transfer.transferred_amount == 80

    amount = 50
    direct_transfer(app1, app2, token_address, amount)
    last_transfer = get_sent_transfer(channel_1_2, 0)
    assert last_transfer.transferred_amount == 50

    amount = 30
    mediated_transfer(app0, app2, token_address, amount)
    last_transfer = get_sent_transfer(channel_0_1, 0)
    assert isinstance(last_transfer, DirectTransfer)

    initiator_transfer = get_sent_transfer(channel_0_3, 0)
    mediator_transfer = get_sent_transfer(channel_3_2, 0)
    assert initiator_transfer.identifier == mediator_transfer.identifier
    assert initiator_transfer.lock.amount == amount
    assert mediator_transfer.lock.amount == amount
Example #4
0
def test_refund_messages(raiden_chain, token_addresses, deposit):
    # The network has the following topology:
    #
    #   App0 <---> App1 <---> App2
    app0, app1, app2 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking

    token_address = token_addresses[0]
    channel_1_0 = channel(app1, app0, token_address)
    channel_1_2 = channel(app1, app2, token_address)

    # Exhaust the channel App1 <-> App2 (to force the refund transfer)
    amount = deposit
    direct_transfer(app1, app2, token_address, amount, identifier=1)
    assert get_sent_transfer(channel_1_2, 0).transferred_amount == amount

    amount = int(deposit / 2.)
    identifier = 1
    async_result = app0.raiden.mediated_transfer_async(
        token_address,
        amount,
        app2.raiden.address,
        identifier,
    )
    assert async_result.wait(
    ) is False, 'Must fail, there are no routes available'

    refund_transfer = get_sent_transfer(channel_1_0, 0)
    assert isinstance(refund_transfer, RefundTransfer)
    assert refund_transfer.lock.amount == amount
Example #5
0
def test_settled_lock(assets_addresses, raiden_network, settle_timeout):
    """ Any transfer following a secret revealed must update the locksroot, so
    that an attacker cannot reuse a secret to double claim a lock.
    """
    asset = assets_addresses[0]
    amount = 30

    app0, app1, app2, app3 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    # mediated transfer
    secret = pending_mediated_transfer(raiden_network, asset, amount)
    hashlock = sha3(secret)

    # get a proof for the pending transfer
    back_channel = channel(app1, app0, asset)
    secret_transfer = get_received_transfer(back_channel, 0)
    lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock)
    unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock(
        secret, lock)

    # reveal the secret
    claim_lock(raiden_network, asset, secret)

    # a new transfer to update the hashlock
    direct_transfer(app0, app1, asset, amount)

    forward_channel = channel(app0, app1, asset)
    last_transfer = get_sent_transfer(forward_channel, 1)

    # call close giving the secret for a transfer that has being revealed
    back_channel.external_state.netting_channel.close(app1.raiden.address,
                                                      last_transfer, None)

    # check that the double unlock will failed
    with pytest.raises(Exception):
        back_channel.external_state.netting_channel.unlock(
            app1.raiden.address,
            [(unlock_proof, secret_transfer.lock.as_bytes, secret)],
        )

    # forward the block number to allow settle
    settle_expiration = app2.raiden.chain.block_number() + settle_timeout
    wait_until_block(app2.raiden.chain, settle_expiration)

    back_channel.external_state.netting_channel.settle()

    participant0 = back_channel.external_state.netting_channel.contract.participants[
        app0.raiden.address]
    participant1 = back_channel.external_state.netting_channel.contract.participants[
        app1.raiden.address]

    assert participant0.netted == participant0.deposit - amount * 2
    assert participant1.netted == participant1.deposit + amount * 2
Example #6
0
def test_settled_lock(assets_addresses, raiden_network, settle_timeout):
    """ Any transfer following a secret revealed must update the locksroot, so
    that an attacker cannot reuse a secret to double claim a lock.
    """
    asset = assets_addresses[0]
    amount = 30

    app0, app1, app2, app3 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    # mediated transfer
    secret = pending_mediated_transfer(raiden_network, asset, amount)

    # get a proof for the pending transfer
    back_channel = channel(app1, app0, asset)
    secret_transfer = get_received_transfer(back_channel, 0)
    merkle_proof = back_channel.our_state.locked.get_proof(secret_transfer)

    # reveal the secret
    register_secret(raiden_network, asset, secret)

    # a new transfer to update the hashlock
    direct_transfer(app0, app1, asset, amount)

    forward_channel = channel(app0, app1, asset)
    last_transfer = get_sent_transfer(forward_channel, 1)

    # call close giving the secret for a transfer that has being revealed
    back_channel.external_state.netting_channel.close(
        app1.raiden.address,
        last_transfer,
        None
    )

    # check that the double unlock will failed
    with pytest.raises(Exception):
        back_channel.external_state.netting_channel.unlock(
            app1.raiden.address,
            [(merkle_proof, secret_transfer.lock.as_bytes, secret)],
        )

    # forward the block number to allow settle
    for _ in range(settle_timeout):
        app2.raiden.chain.next_block()

    back_channel.external_state.netting_channel.settle()

    participant0 = back_channel.external_state.netting_channel.contract.participants[app0.raiden.address]
    participant1 = back_channel.external_state.netting_channel.contract.participants[app1.raiden.address]

    assert participant0.netted == participant0.deposit - amount * 2
    assert participant1.netted == participant1.deposit + amount * 2
Example #7
0
def test_settled_lock(assets_addresses, raiden_network, settle_timeout, reveal_timeout):
    """ Any transfer following a secret revealed must update the locksroot, so
    that an attacker cannot reuse a secret to double claim a lock.
    """
    asset = assets_addresses[0]
    amount = 30

    app0, app1, app2, _ = raiden_network  # pylint: disable=unbalanced-tuple-unpacking
    address0 = app0.raiden.address
    address1 = app1.raiden.address

    # mediated transfer
    identifier = 1
    expiration = app0.raiden.chain.block_number() + settle_timeout - reveal_timeout
    secret = pending_mediated_transfer(
        raiden_network,
        asset,
        amount,
        identifier,
        expiration,
    )
    hashlock = sha3(secret)

    # get a proof for the pending transfer
    back_channel = channel(app1, app0, asset)
    secret_transfer = get_received_transfer(back_channel, 0)
    lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock)
    unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock(secret, lock)

    # reveal the secret
    claim_lock(raiden_network, asset, secret)

    # a new transfer to update the hashlock
    direct_transfer(app0, app1, asset, amount)

    forward_channel = channel(app0, app1, asset)
    last_transfer = get_sent_transfer(forward_channel, 1)

    # call close giving the secret for a transfer that has being revealed
    back_channel.external_state.netting_channel.close(
        app1.raiden.address,
        last_transfer,
        None
    )

    # check that the double unlock will failed
    with pytest.raises(Exception):
        back_channel.external_state.netting_channel.unlock(
            app1.raiden.address,
            [(unlock_proof, secret_transfer.lock.as_bytes, secret)],
        )

    # forward the block number to allow settle
    settle_expiration = app2.raiden.chain.block_number() + settle_timeout
    wait_until_block(app2.raiden.chain, settle_expiration)

    back_channel.external_state.netting_channel.settle()

    participant0 = back_channel.external_state.netting_channel.contract.participants[address0]
    participant1 = back_channel.external_state.netting_channel.contract.participants[address1]

    assert participant0.netted == participant0.deposit - amount * 2
    assert participant1.netted == participant1.deposit + amount * 2
Example #8
0
def test_settled_lock(token_addresses, raiden_network, settle_timeout,
                      reveal_timeout):
    """ Any transfer following a secret revealed must update the locksroot, so
    that an attacker cannot reuse a secret to double claim a lock.
    """
    token = token_addresses[0]
    amount = 30

    app0, app1, app2, _ = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    address0 = app0.raiden.address
    address1 = app1.raiden.address

    forward_channel = channel(app0, app1, token)
    back_channel = channel(app1, app0, token)

    deposit0 = forward_channel.contract_balance
    deposit1 = back_channel.contract_balance

    token_contract = app0.raiden.chain.token(token)
    balance0 = token_contract.balance_of(address0)
    balance1 = token_contract.balance_of(address1)

    # mediated transfer
    identifier = 1
    expiration = app0.raiden.chain.block_number(
    ) + settle_timeout - reveal_timeout
    secret = pending_mediated_transfer(
        raiden_network,
        token,
        amount,
        identifier,
        expiration,
    )
    hashlock = sha3(secret)

    # get a proof for the pending transfer
    secret_transfer = get_received_transfer(back_channel, 0)
    lock = back_channel.our_state.balance_proof.get_lock_by_hashlock(hashlock)
    unlock_proof = back_channel.our_state.balance_proof.compute_proof_for_lock(
        secret, lock)

    # reveal the secret
    claim_lock(raiden_network, token, secret)

    # a new transfer to update the hashlock
    direct_transfer(app0, app1, token, amount)

    last_transfer = get_sent_transfer(forward_channel, 1)

    # call close giving the secret for a transfer that has being revealed
    back_channel.external_state.netting_channel.close(last_transfer)

    # check that the double unlock will fail
    with pytest.raises(Exception):
        back_channel.external_state.netting_channel.withdraw(
            [(unlock_proof, secret_transfer.lock.as_bytes, secret)], )

    # forward the block number to allow settle
    settle_expiration = app2.raiden.chain.block_number() + settle_timeout
    wait_until_block(app2.raiden.chain, settle_expiration)

    back_channel.external_state.netting_channel.settle()

    assert token_contract.balance_of(
        address0) == balance0 + deposit0 - amount * 2
    assert token_contract.balance_of(
        address1) == balance1 + deposit1 + amount * 2
Example #9
0
def test_fullnetwork(raiden_chain, token_addresses, deposit, settle_timeout,
                     reveal_timeout):
    # pylint: disable=too-many-locals,too-many-statements

    # The network has the following topology:
    #
    #   App0 <---> App1
    #    ^          ^
    #    |          |
    #    v          v
    #   App3 <---> App2

    token_address = token_addresses[0]

    app0, app1, app2, app3 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    channel_0_1 = channel(app0, app1, token_address)
    channel_3_2 = channel(app3, app2, token_address)
    channel_0_3 = channel(app0, app3, token_address)

    # Exhaust the channel deposit (to force the mediated transfer to go backwards)
    amount = deposit
    direct_transfer(app0, app1, token_address, amount, identifier=1)
    assert get_sent_transfer(channel_0_1, 0).transferred_amount == amount

    amount = int(deposit / 2.)
    mediated_transfer(app0, app2, token_address, amount)

    gevent.sleep(0.5)

    # This is the only possible path, the transfer must go backwards
    assert_path_mediated_transfer(
        get_sent_transfer(channel_0_3, 0),
        get_sent_transfer(channel_3_2, 0),
    )

    app0_state_changes = [
        change[1]
        for change in get_all_state_changes(app0.raiden.transaction_log)
    ]

    app0_events = [
        event.event_object
        for event in get_all_state_events(app0.raiden.transaction_log)
    ]

    secret = None
    for event in app0_events:
        if isinstance(event, SendRevealSecret):
            secret = event.secret

    assert secret is not None
    hashlock = sha3(secret)

    # app0 initiates the direct transfer and mediated_transfer
    assert must_contain_entry(
        app0_state_changes, ActionInitInitiator, {
            'our_address': app0.raiden.address,
            'transfer': {
                'amount': amount,
                'token': token_address,
                'initiator': app0.raiden.address,
                'target': app2.raiden.address,
                'expiration': None,
                'hashlock': None,
                'secret': None,
            }
        })

    # Of these 2 the state machine will in the future choose the one with the most
    # available balance
    not_taken_route = RouteState(
        state='opened',
        node_address=app1.raiden.address,
        channel_address=channel_0_1.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )

    taken_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )

    for state_change in app0_state_changes:
        if isinstance(state_change, ActionInitMediator):
            assert taken_route in state_change.routes.available_routes
            assert not_taken_route not in state_change.routes.available_routes

    # app1 received one direct transfers
    app1_state_changes = [
        change[1]
        for change in get_all_state_changes(app1.raiden.transaction_log)
    ]
    assert must_contain_entry(app1_state_changes, ReceiveBalanceProof, {})
    assert must_contain_entry(app1_state_changes, ReceiveTransferDirect, {})

    app2_state_changes = [
        change[1]
        for change in get_all_state_changes(app2.raiden.transaction_log)
    ]

    assert must_contain_entry(
        app2_state_changes, ActionInitTarget, {
            'our_address': app2.raiden.address,
            'from_route': {
                'state': 'opened',
                'node_address': app3.raiden.address,
                'channel_address': channel_3_2.channel_address,
                'available_balance': deposit,
                'settle_timeout': settle_timeout,
                'reveal_timeout': reveal_timeout,
                'closed_block': None
            },
            'from_transfer': {
                'amount': amount,
                'hashlock': hashlock,
                'token': token_address,
                'initiator': app0.raiden.address,
                'target': app2.raiden.address,
            }
        })

    assert must_contain_entry(app2_state_changes, ReceiveSecretReveal, {
        'sender': app0.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app2_state_changes, ReceiveSecretReveal, {
        'sender': app3.raiden.address,
        'secret': secret,
    })

    app2_events = [
        event.event_object
        for event in get_all_state_events(app2.raiden.transaction_log)
    ]

    assert must_contain_entry(app2_events, SendSecretRequest, {
        'amount': amount,
        'hashlock': hashlock,
        'receiver': app0.raiden.address,
    })

    assert must_contain_entry(
        app2_events, SendRevealSecret, {
            'token': token_address,
            'secret': secret,
            'receiver': app3.raiden.address,
            'sender': app2.raiden.address,
        })

    assert must_contain_entry(app0_state_changes, ReceiveSecretRequest, {
        'amount': amount,
        'sender': app2.raiden.address,
        'hashlock': hashlock,
    })

    assert must_contain_entry(app0_state_changes, ReceiveSecretReveal, {
        'sender': app3.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app0_events, EventTransferSentSuccess, {})

    assert must_contain_entry(
        app0_events, SendMediatedTransfer, {
            'token': token_address,
            'amount': amount,
            'hashlock': hashlock,
            'initiator': app0.raiden.address,
            'target': app2.raiden.address,
            'receiver': app3.raiden.address,
        })

    assert must_contain_entry(
        app0_events, SendRevealSecret, {
            'secret': secret,
            'token': token_address,
            'receiver': app2.raiden.address,
            'sender': app0.raiden.address,
        })

    assert must_contain_entry(
        app0_events, SendBalanceProof, {
            'token': token_address,
            'channel_address': channel_0_3.channel_address,
            'receiver': app3.raiden.address,
            'secret': secret,
        })

    assert must_contain_entry(app0_events, EventTransferSentSuccess, {})
    assert must_contain_entry(app0_events, EventUnlockSuccess, {
        'hashlock': hashlock,
    })

    app3_state_changes = [
        change[1]
        for change in get_all_state_changes(app3.raiden.transaction_log)
    ]

    assert must_contain_entry(
        app3_state_changes, ActionInitMediator, {
            'our_address': app3.raiden.address,
            'from_route': {
                'state': 'opened',
                'node_address': app0.raiden.address,
                'channel_address': channel_0_3.channel_address,
                'available_balance': deposit,
                'settle_timeout': settle_timeout,
                'reveal_timeout': reveal_timeout,
                'closed_block': None,
            },
            'from_transfer': {
                'amount': amount,
                'hashlock': hashlock,
                'token': token_address,
                'initiator': app0.raiden.address,
                'target': app2.raiden.address,
            }
        })

    assert must_contain_entry(app3_state_changes, ReceiveSecretReveal, {
        'sender': app2.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app3_state_changes, ReceiveSecretReveal, {
        'sender': app2.raiden.address,
        'secret': secret,
    })

    app3_events = [
        event.event_object
        for event in get_all_state_events(app3.raiden.transaction_log)
    ]

    assert must_contain_entry(
        app3_events, SendMediatedTransfer, {
            'token': token_address,
            'amount': amount,
            'hashlock': hashlock,
            'initiator': app0.raiden.address,
            'target': app2.raiden.address,
            'receiver': app2.raiden.address,
        })

    assert must_contain_entry(
        app3_events, SendRevealSecret, {
            'secret': secret,
            'token': token_address,
            'receiver': app0.raiden.address,
            'sender': app3.raiden.address,
        })

    assert must_contain_entry(
        app3_events, SendBalanceProof, {
            'token': token_address,
            'channel_address': channel_3_2.channel_address,
            'receiver': app2.raiden.address,
            'secret': secret,
        })
    assert must_contain_entry(app3_events, EventUnlockSuccess, {})
Example #10
0
def test_fullnetwork(raiden_chain, settle_timeout, reveal_timeout):
    app0, app1, app2, app3 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = app0.raiden.chain.default_registry.token_addresses()[0]
    channel_0_1 = channel(app0, app1, token_address)
    channel_1_2 = channel(app1, app2, token_address)
    channel_3_2 = channel(app3, app2, token_address)
    channel_0_3 = channel(app0, app3, token_address)

    amount = 80
    direct_transfer(app0, app1, token_address, amount)
    last_transfer = get_sent_transfer(channel_0_1, 0)
    assert last_transfer.transferred_amount == 80

    amount = 50
    direct_transfer(app1, app2, token_address, amount)
    last_transfer = get_sent_transfer(channel_1_2, 0)
    assert last_transfer.transferred_amount == 50

    amount = 30
    mediated_transfer(app0, app2, token_address, amount)
    last_transfer = get_sent_transfer(channel_0_1, 0)
    assert isinstance(last_transfer, DirectTransfer)

    initiator_transfer = get_sent_transfer(channel_0_3, 0)
    mediator_transfer = get_sent_transfer(channel_3_2, 0)
    assert initiator_transfer.identifier == mediator_transfer.identifier
    assert initiator_transfer.lock.amount == amount
    assert mediator_transfer.lock.amount == amount

    # Now let's query the WAL to see if the state changes were logged as expected
    app0_state_changes = [
        change[1]
        for change in get_all_state_changes(app0.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app0_events = [
        event[2] for event in get_all_state_events(app0.raiden.transaction_log)
    ]
    app1_state_changes = [
        change[1]
        for change in get_all_state_changes(app1.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app1_events = [
        event[2] for event in get_all_state_events(app1.raiden.transaction_log)
    ]
    app2_state_changes = [
        change[1]
        for change in get_all_state_changes(app2.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app2_events = [
        event[2] for event in get_all_state_events(app2.raiden.transaction_log)
    ]
    app3_state_changes = [
        change[1]
        for change in get_all_state_changes(app3.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app3_events = [
        event[2] for event in get_all_state_events(app3.raiden.transaction_log)
    ]

    # app1 does not take part in the mediated transfer.
    assert len(app1_state_changes) == 0
    assert len(app1_events) == 0

    # app0 initiates the mediated_transfer
    assert len(app0_state_changes) == 3
    assert isinstance(app0_state_changes[0], ActionInitInitiator)
    assert app0_state_changes[0].our_address == app0.raiden.address
    assert app0_state_changes[0].transfer.amount == amount
    assert app0_state_changes[0].transfer.token == token_address
    assert app0_state_changes[0].transfer.initiator == app0.raiden.address
    assert app0_state_changes[0].transfer.target == app2.raiden.address
    # The ActionInitInitiator state change does not have the following fields populated.
    # They get populated via an event during the processing of the state change inside
    # this function: mediated_transfer.mediated_transfer.initiator.try_new_route()
    assert app0_state_changes[0].transfer.expiration is None
    assert app0_state_changes[0].transfer.hashlock is None
    assert app0_state_changes[0].transfer.secret is None
    # We should have two available routes
    assert len(app0_state_changes[0].routes.available_routes) == 2
    assert len(app0_state_changes[0].routes.ignored_routes) == 0
    assert len(app0_state_changes[0].routes.refunded_routes) == 0
    assert len(app0_state_changes[0].routes.canceled_routes) == 0
    # Of these 2 the state machine will in the future choose the one with the most
    # available balance
    not_taken_route = RouteState(
        state='opened',
        node_address=app1.raiden.address,
        channel_address=channel_0_1.channel_address,
        available_balance=1048496,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    taken_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=1048576,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    assert taken_route in app0_state_changes[0].routes.available_routes
    assert not_taken_route in app0_state_changes[0].routes.available_routes

    # app0 will also receive a secret request from the target
    assert isinstance(app0_state_changes[1], ReceiveSecretRequest)
    assert app0_state_changes[1].amount == amount
    assert app0_state_changes[1].sender == app2.raiden.address
    hashlock = app0_state_changes[1].hashlock

    # app0 will also receive a secret reveal from the immediate neighbour
    assert isinstance(app0_state_changes[2], ReceiveSecretReveal)
    assert app0_state_changes[2].sender == app3.raiden.address
    secret = app0_state_changes[2].secret
    assert sha3(secret) == hashlock

    # check app0 state events
    assert len(app0_events) == 4
    assert isinstance(app0_events[0], SendMediatedTransfer)
    assert app0_events[0].token == token_address
    assert app0_events[0].amount == amount
    assert app0_events[0].hashlock == hashlock
    assert app0_events[0].initiator == app0.raiden.address
    assert app0_events[0].target == app2.raiden.address
    assert app0_events[0].receiver == app3.raiden.address
    assert isinstance(app0_events[1], SendRevealSecret)
    assert app0_events[1].secret == secret
    assert app0_events[1].token == token_address
    assert app0_events[1].receiver == app2.raiden.address
    assert app0_events[1].sender == app0.raiden.address
    assert isinstance(app0_events[2], SendBalanceProof)
    assert app0_events[2].token == token_address
    assert app0_events[2].channel_address == channel_0_3.channel_address
    assert app0_events[2].receiver == app3.raiden.address
    assert app0_events[2].secret == secret
    assert isinstance(app0_events[3], EventTransferCompleted)
    assert app0_events[3].secret == secret
    assert app0_events[3].hashlock == hashlock

    # app3 is the mediator
    assert isinstance(app3_state_changes[0], ActionInitMediator)
    assert app3_state_changes[0].our_address == app3.raiden.address
    # We should have only 1 available route from mediator to target
    from_route = RouteState(
        state='opened',
        node_address=app0.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=1048576,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    to_route = RouteState(
        state='opened',
        node_address=app2.raiden.address,
        channel_address=channel_3_2.channel_address,
        available_balance=1048576,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    assert app3_state_changes[0].from_route == from_route
    assert len(app3_state_changes[0].routes.available_routes) == 1
    assert len(app3_state_changes[0].routes.ignored_routes) == 0
    assert len(app3_state_changes[0].routes.refunded_routes) == 0
    assert len(app3_state_changes[0].routes.canceled_routes) == 0
    assert app3_state_changes[0].routes.available_routes[0] == to_route
    # check the from_transfer is correct
    assert app3_state_changes[0].from_transfer.amount == amount
    assert app3_state_changes[0].from_transfer.hashlock == hashlock
    assert app3_state_changes[0].from_transfer.token == token_address
    assert app3_state_changes[0].from_transfer.initiator == app0.raiden.address
    assert app3_state_changes[0].from_transfer.target == app2.raiden.address

    # The mediator should have also received a SecretReveal from the target
    assert isinstance(app3_state_changes[1], ReceiveSecretReveal)
    assert app3_state_changes[1].sender == app2.raiden.address
    assert app3_state_changes[1].secret == secret

    # If the mediator received any more it is from the initiator
    # TODO: Figure out why we may get two times the secret reveal from the initiator
    for state_change in app3_state_changes[2:]:
        assert isinstance(state_change, ReceiveSecretReveal)
        assert state_change.sender == app0.raiden.address
        assert state_change.secret == secret

    # check app3 state events
    assert len(app3_events) == 3
    assert isinstance(app3_events[0], SendMediatedTransfer)
    assert app3_events[0].token == token_address
    assert app3_events[0].amount == amount
    assert app3_events[0].hashlock == hashlock
    assert app3_events[0].initiator == app0.raiden.address
    assert app3_events[0].target == app2.raiden.address
    assert app3_events[0].receiver == app2.raiden.address
    assert isinstance(app3_events[1], SendRevealSecret)
    assert app3_events[1].secret == secret
    assert app3_events[1].token == token_address
    assert app3_events[1].receiver == app0.raiden.address
    assert app3_events[1].sender == app3.raiden.address
    assert isinstance(app3_events[2], SendBalanceProof)
    assert app3_events[2].token == token_address
    assert app3_events[2].channel_address == channel_3_2.channel_address
    assert app3_events[2].receiver == app2.raiden.address
    assert app3_events[2].secret == secret

    # app2 is the target of the mediated transfer
    assert len(app2_state_changes
               ) == 4  # We get 2 secret reveals from the mediator. WHY?
    assert isinstance(app2_state_changes[0], ActionInitTarget)
    assert app2_state_changes[0].our_address == app2.raiden.address
    # check the route the transfer came from
    from_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_3_2.channel_address,
        available_balance=1048576,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    assert app2_state_changes[0].from_route == from_route
    # check the from_transfer is correct
    assert app2_state_changes[0].from_transfer.amount == amount
    assert app2_state_changes[0].from_transfer.hashlock == hashlock
    assert app2_state_changes[0].from_transfer.token == token_address
    assert app2_state_changes[0].from_transfer.initiator == app0.raiden.address
    assert app2_state_changes[0].from_transfer.target == app2.raiden.address

    # We also get secret reveals from the initiator and the mediator.
    assert isinstance(app2_state_changes[1], ReceiveSecretReveal)
    assert app2_state_changes[1].sender == app0.raiden.address
    assert app2_state_changes[1].secret == secret

    # TODO: Figure out why we get two times the Secret Reveal from the mediator
    assert isinstance(app2_state_changes[2], ReceiveSecretReveal)
    assert app2_state_changes[2].sender == app3.raiden.address
    assert app2_state_changes[2].secret == secret
    assert isinstance(app2_state_changes[3], ReceiveSecretReveal)
    assert app2_state_changes[3].sender == app3.raiden.address
    assert app2_state_changes[3].secret == secret

    # check app2 state events
    assert len(app2_events) == 2
    assert isinstance(app2_events[0], SendSecretRequest)
    assert app2_events[0].amount == amount
    assert app2_events[0].hashlock == hashlock
    assert app2_events[0].receiver == app0.raiden.address
    assert isinstance(app2_events[1], SendRevealSecret)
    assert app2_events[1].token == token_address
    assert app2_events[1].secret == secret
    assert app2_events[1].receiver == app3.raiden.address
    assert app2_events[1].sender == app2.raiden.address
Example #11
0
def test_fullnetwork(raiden_chain, token_addresses, deposit, settle_timeout,
                     reveal_timeout):

    # The network has the following topology:
    #
    #   App0 <---> App1
    #    ^          ^
    #    |          |
    #    v          v
    #   App3 <---> App2

    token_address = token_addresses[0]

    app0, app1, app2, app3 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    channel_0_1 = channel(app0, app1, token_address)
    channel_3_2 = channel(app3, app2, token_address)
    channel_0_3 = channel(app0, app3, token_address)

    # Exhaust the channel deposit (to force the mediated transfer to go backwards)
    amount = deposit
    direct_transfer(app0, app1, token_address, amount)
    assert get_sent_transfer(channel_0_1, 0).transferred_amount == amount

    amount = int(deposit / 2.)
    mediated_transfer(app0, app2, token_address, amount)

    # This is the only possible path, the transfer must go backwards
    assert_path_mediated_transfer(
        get_sent_transfer(channel_0_3, 0),
        get_sent_transfer(channel_3_2, 0),
    )

    # Now let's query the WAL to see if the state changes were logged as expected
    app0_state_changes = [
        change[1]
        for change in get_all_state_changes(app0.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app0_events = [
        event.event_object
        for event in get_all_state_events(app0.raiden.transaction_log)
    ]
    app1_state_changes = [
        change[1]
        for change in get_all_state_changes(app1.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app1_events = [
        event.event_object
        for event in get_all_state_events(app1.raiden.transaction_log)
    ]
    app2_state_changes = [
        change[1]
        for change in get_all_state_changes(app2.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app2_events = [
        event.event_object
        for event in get_all_state_events(app2.raiden.transaction_log)
    ]
    app3_state_changes = [
        change[1]
        for change in get_all_state_changes(app3.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]
    app3_events = [
        event.event_object
        for event in get_all_state_events(app3.raiden.transaction_log)
    ]

    # app1 received one direct transfers
    assert len(app1_state_changes) == 1
    assert len(app1_events) == 1

    # app0 initiates the direct transfer and mediated_transfer
    assert len(app0_state_changes) == 4
    assert isinstance(app0_state_changes[1], ActionInitInitiator)
    assert app0_state_changes[1].our_address == app0.raiden.address
    assert app0_state_changes[1].transfer.amount == amount
    assert app0_state_changes[1].transfer.token == token_address
    assert app0_state_changes[1].transfer.initiator == app0.raiden.address
    assert app0_state_changes[1].transfer.target == app2.raiden.address
    # The ActionInitInitiator state change does not have the following fields populated.
    # They get populated via an event during the processing of the state change inside
    # this function: mediated_transfer.mediated_transfer.initiator.try_new_route()
    assert app0_state_changes[1].transfer.expiration is None
    assert app0_state_changes[1].transfer.hashlock is None
    assert app0_state_changes[1].transfer.secret is None
    # We should have one available route
    assert len(app0_state_changes[1].routes.available_routes) == 1
    assert len(app0_state_changes[1].routes.ignored_routes) == 0
    assert len(app0_state_changes[1].routes.refunded_routes) == 0
    assert len(app0_state_changes[1].routes.canceled_routes) == 0
    # Of these 2 the state machine will in the future choose the one with the most
    # available balance
    not_taken_route = RouteState(
        state='opened',
        node_address=app1.raiden.address,
        channel_address=channel_0_1.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    taken_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    assert taken_route in app0_state_changes[1].routes.available_routes
    assert not_taken_route not in app0_state_changes[1].routes.available_routes

    # app0 will also receive a secret request from the target
    assert isinstance(app0_state_changes[2], ReceiveSecretRequest)
    assert app0_state_changes[2].amount == amount
    assert app0_state_changes[2].sender == app2.raiden.address
    hashlock = app0_state_changes[2].hashlock

    # app0 will also receive a secret reveal from the immediate neighbour
    assert isinstance(app0_state_changes[3], ReceiveSecretReveal)
    assert app0_state_changes[3].sender == app3.raiden.address
    secret = app0_state_changes[3].secret
    assert sha3(secret) == hashlock

    assert len(app0_events) == 6

    # Direct transfer
    assert isinstance(app0_events[0], EventTransferSentSuccess)

    # not checking the expiration and identifier
    assert isinstance(app0_events[1], SendMediatedTransfer)
    assert app0_events[1].token == token_address
    assert app0_events[1].amount == amount
    assert app0_events[1].hashlock == hashlock
    assert app0_events[1].initiator == app0.raiden.address
    assert app0_events[1].target == app2.raiden.address
    assert app0_events[1].receiver == app3.raiden.address

    #  not checking the identifier
    assert isinstance(app0_events[2], SendRevealSecret)
    assert app0_events[2].secret == secret
    assert app0_events[2].token == token_address
    assert app0_events[2].receiver == app2.raiden.address
    assert app0_events[2].sender == app0.raiden.address

    # not checking the identifier
    assert isinstance(app0_events[3], SendBalanceProof)
    assert app0_events[3].token == token_address
    assert app0_events[3].channel_address == channel_0_3.channel_address
    assert app0_events[3].receiver == app3.raiden.address
    assert app0_events[3].secret == secret

    assert isinstance(app0_events[4], EventTransferSentSuccess)

    # EventUnlockSuccess, not checking the identifier
    assert isinstance(app0_events[5], EventUnlockSuccess)
    assert app0_events[5].hashlock == hashlock

    # app3 is the mediator
    assert isinstance(app3_state_changes[0], ActionInitMediator)
    assert app3_state_changes[0].our_address == app3.raiden.address
    # We should have only 1 available route from mediator to target
    from_route = RouteState(
        state='opened',
        node_address=app0.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    to_route = RouteState(
        state='opened',
        node_address=app2.raiden.address,
        channel_address=channel_3_2.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )

    assert app3_state_changes[0].from_route == from_route
    assert len(app3_state_changes[0].routes.available_routes) == 1
    assert len(app3_state_changes[0].routes.ignored_routes) == 0
    assert len(app3_state_changes[0].routes.refunded_routes) == 0
    assert len(app3_state_changes[0].routes.canceled_routes) == 0
    assert app3_state_changes[0].routes.available_routes[0] == to_route
    # check the from_transfer is correct
    assert app3_state_changes[0].from_transfer.amount == amount
    assert app3_state_changes[0].from_transfer.hashlock == hashlock
    assert app3_state_changes[0].from_transfer.token == token_address
    assert app3_state_changes[0].from_transfer.initiator == app0.raiden.address
    assert app3_state_changes[0].from_transfer.target == app2.raiden.address

    # The mediator should have also received a SecretReveal from the target
    assert isinstance(app3_state_changes[1], ReceiveSecretReveal)
    assert app3_state_changes[1].sender == app2.raiden.address
    assert app3_state_changes[1].secret == secret

    # If the mediator received any more it is from the initiator
    # TODO: Figure out why we may get two times the secret reveal from the initiator
    for state_change in app3_state_changes[2:]:
        assert isinstance(state_change, ReceiveSecretReveal)
        assert state_change.sender == app0.raiden.address
        assert state_change.secret == secret

    # check app3 state events
    assert len(app3_events) == 4
    assert isinstance(app3_events[0], SendMediatedTransfer)
    assert app3_events[0].token == token_address
    assert app3_events[0].amount == amount
    assert app3_events[0].hashlock == hashlock
    assert app3_events[0].initiator == app0.raiden.address
    assert app3_events[0].target == app2.raiden.address
    assert app3_events[0].receiver == app2.raiden.address

    assert isinstance(app3_events[1], SendRevealSecret)
    assert app3_events[1].secret == secret
    assert app3_events[1].token == token_address
    assert app3_events[1].receiver == app0.raiden.address
    assert app3_events[1].sender == app3.raiden.address

    assert isinstance(app3_events[2], SendBalanceProof)
    assert app3_events[2].token == token_address
    assert app3_events[2].channel_address == channel_3_2.channel_address
    assert app3_events[2].receiver == app2.raiden.address
    assert app3_events[2].secret == secret

    assert isinstance(app3_events[3], EventUnlockSuccess)

    # app2 is the target of the mediated transfer
    assert len(app2_state_changes
               ) == 4  # We get 2 secret reveals from the mediator. WHY?
    assert isinstance(app2_state_changes[0], ActionInitTarget)
    assert app2_state_changes[0].our_address == app2.raiden.address
    # check the route the transfer came from
    from_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_3_2.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )
    assert app2_state_changes[0].from_route == from_route
    # check the from_transfer is correct
    assert app2_state_changes[0].from_transfer.amount == amount
    assert app2_state_changes[0].from_transfer.hashlock == hashlock
    assert app2_state_changes[0].from_transfer.token == token_address
    assert app2_state_changes[0].from_transfer.initiator == app0.raiden.address
    assert app2_state_changes[0].from_transfer.target == app2.raiden.address

    # We also get secret reveals from the initiator and the mediator.
    assert isinstance(app2_state_changes[1], ReceiveSecretReveal)
    assert app2_state_changes[1].sender == app0.raiden.address
    assert app2_state_changes[1].secret == secret

    # TODO: Figure out why we get two times the Secret Reveal from the mediator
    assert isinstance(app2_state_changes[2], ReceiveSecretReveal)
    assert app2_state_changes[2].sender == app3.raiden.address
    assert app2_state_changes[2].secret == secret
    assert isinstance(app2_state_changes[3], ReceiveSecretReveal)
    assert app2_state_changes[3].sender == app3.raiden.address
    assert app2_state_changes[3].secret == secret

    # check app2 state events
    assert len(app2_events) == 2
    assert isinstance(app2_events[0], SendSecretRequest)
    assert app2_events[0].amount == amount
    assert app2_events[0].hashlock == hashlock
    assert app2_events[0].receiver == app0.raiden.address
    assert isinstance(app2_events[1], SendRevealSecret)
    assert app2_events[1].token == token_address
    assert app2_events[1].secret == secret
    assert app2_events[1].receiver == app3.raiden.address
    assert app2_events[1].sender == app2.raiden.address
def test_fullnetwork(
        raiden_chain,
        token_addresses,
        deposit,
        settle_timeout,
        reveal_timeout):
    # pylint: disable=too-many-locals,too-many-statements

    # The network has the following topology:
    #
    #   App0 <---> App1
    #    ^          ^
    #    |          |
    #    v          v
    #   App3 <---> App2

    token_address = token_addresses[0]

    app0, app1, app2, app3 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    channel_0_1 = channel(app0, app1, token_address)
    channel_3_2 = channel(app3, app2, token_address)
    channel_0_3 = channel(app0, app3, token_address)

    # Exhaust the channel deposit (to force the mediated transfer to go backwards)
    amount = deposit
    direct_transfer(app0, app1, token_address, amount, identifier=1)
    assert get_sent_transfer(channel_0_1, 0).transferred_amount == amount

    amount = int(deposit / 2.)
    mediated_transfer(
        app0,
        app2,
        token_address,
        amount
    )

    gevent.sleep(0.5)

    # This is the only possible path, the transfer must go backwards
    assert_path_mediated_transfer(
        get_sent_transfer(channel_0_3, 0),
        get_sent_transfer(channel_3_2, 0),
    )

    app0_state_changes = [
        change[1]
        for change in get_all_state_changes(app0.raiden.transaction_log)
    ]

    app0_events = [
        event.event_object
        for event in get_all_state_events(app0.raiden.transaction_log)
    ]

    secret = None
    for event in app0_events:
        if isinstance(event, SendRevealSecret):
            secret = event.secret

    assert secret is not None
    hashlock = sha3(secret)

    # app0 initiates the direct transfer and mediated_transfer
    assert must_contain_entry(app0_state_changes, ActionInitInitiator, {
        'our_address': app0.raiden.address,
        'transfer': {
            'amount': amount,
            'token': token_address,
            'initiator': app0.raiden.address,
            'target': app2.raiden.address,
            'expiration': None,
            'hashlock': None,
            'secret': None,
        }
    })

    # Of these 2 the state machine will in the future choose the one with the most
    # available balance
    not_taken_route = RouteState(
        state='opened',
        node_address=app1.raiden.address,
        channel_address=channel_0_1.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )

    taken_route = RouteState(
        state='opened',
        node_address=app3.raiden.address,
        channel_address=channel_0_3.channel_address,
        available_balance=deposit,
        settle_timeout=settle_timeout,
        reveal_timeout=reveal_timeout,
        closed_block=None,
    )

    for state_change in app0_state_changes:
        if isinstance(state_change, ActionInitMediator):
            assert taken_route in state_change.routes.available_routes
            assert not_taken_route not in state_change.routes.available_routes

    # app1 received one direct transfers
    app1_state_changes = [
        change[1]
        for change in get_all_state_changes(app1.raiden.transaction_log)
    ]
    assert must_contain_entry(app1_state_changes, ReceiveBalanceProof, {})
    assert must_contain_entry(app1_state_changes, ReceiveTransferDirect, {})

    app2_state_changes = [
        change[1]
        for change in get_all_state_changes(app2.raiden.transaction_log)
    ]

    assert must_contain_entry(app2_state_changes, ActionInitTarget, {
        'our_address': app2.raiden.address,
        'from_route': {
            'state': 'opened',
            'node_address': app3.raiden.address,
            'channel_address': channel_3_2.channel_address,
            'available_balance': deposit,
            'settle_timeout': settle_timeout,
            'reveal_timeout': reveal_timeout,
            'closed_block': None
        },
        'from_transfer': {
            'amount': amount,
            'hashlock': hashlock,
            'token': token_address,
            'initiator': app0.raiden.address,
            'target': app2.raiden.address,
        }
    })

    assert must_contain_entry(app2_state_changes, ReceiveSecretReveal, {
        'sender': app0.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app2_state_changes, ReceiveSecretReveal, {
        'sender': app3.raiden.address,
        'secret': secret,
    })

    app2_events = [
        event.event_object
        for event in get_all_state_events(app2.raiden.transaction_log)
    ]

    assert must_contain_entry(app2_events, SendSecretRequest, {
        'amount': amount,
        'hashlock': hashlock,
        'receiver': app0.raiden.address,
    })

    assert must_contain_entry(app2_events, SendRevealSecret, {
        'token': token_address,
        'secret': secret,
        'receiver': app3.raiden.address,
        'sender': app2.raiden.address,
    })

    assert must_contain_entry(app0_state_changes, ReceiveSecretRequest, {
        'amount': amount,
        'sender': app2.raiden.address,
        'hashlock': hashlock,
    })

    assert must_contain_entry(app0_state_changes, ReceiveSecretReveal, {
        'sender': app3.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app0_events, EventTransferSentSuccess, {})

    assert must_contain_entry(app0_events, SendMediatedTransfer, {
        'token': token_address,
        'amount': amount,
        'hashlock': hashlock,
        'initiator': app0.raiden.address,
        'target': app2.raiden.address,
        'receiver': app3.raiden.address,
    })

    assert must_contain_entry(app0_events, SendRevealSecret, {
        'secret': secret,
        'token': token_address,
        'receiver': app2.raiden.address,
        'sender': app0.raiden.address,
    })

    assert must_contain_entry(app0_events, SendBalanceProof, {
        'token': token_address,
        'channel_address': channel_0_3.channel_address,
        'receiver': app3.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app0_events, EventTransferSentSuccess, {})
    assert must_contain_entry(app0_events, EventUnlockSuccess, {
        'hashlock': hashlock,
    })

    app3_state_changes = [
        change[1]
        for change in get_all_state_changes(app3.raiden.transaction_log)
    ]

    assert must_contain_entry(app3_state_changes, ActionInitMediator, {
        'our_address': app3.raiden.address,
        'from_route': {
            'state': 'opened',
            'node_address': app0.raiden.address,
            'channel_address': channel_0_3.channel_address,
            'available_balance': deposit,
            'settle_timeout': settle_timeout,
            'reveal_timeout': reveal_timeout,
            'closed_block': None,
        },
        'from_transfer': {
            'amount': amount,
            'hashlock': hashlock,
            'token': token_address,
            'initiator': app0.raiden.address,
            'target': app2.raiden.address,
        }
    })

    assert must_contain_entry(app3_state_changes, ReceiveSecretReveal, {
        'sender': app2.raiden.address,
        'secret': secret,
    })

    assert must_contain_entry(app3_state_changes, ReceiveSecretReveal, {
        'sender': app2.raiden.address,
        'secret': secret,
    })

    app3_events = [
        event.event_object
        for event in get_all_state_events(app3.raiden.transaction_log)
    ]

    assert must_contain_entry(app3_events, SendMediatedTransfer, {
        'token': token_address,
        'amount': amount,
        'hashlock': hashlock,
        'initiator': app0.raiden.address,
        'target': app2.raiden.address,
        'receiver': app2.raiden.address,
    })

    assert must_contain_entry(app3_events, SendRevealSecret, {
        'secret': secret,
        'token': token_address,
        'receiver': app0.raiden.address,
        'sender': app3.raiden.address,
    })

    assert must_contain_entry(app3_events, SendBalanceProof, {
        'token': token_address,
        'channel_address': channel_3_2.channel_address,
        'receiver': app2.raiden.address,
        'secret': secret,
    })
    assert must_contain_entry(app3_events, EventUnlockSuccess, {})