def test_target_log_directransfer_message(
        raiden_chain,
        token_addresses,
        deposit):

    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 21

    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app1_state_changes = get_all_state_changes(app1.raiden.transaction_log)
    received_transfers = [
        state_change
        for _, state_change in app1_state_changes
        if isinstance(state_change, ReceiveTransferDirect)
    ]
    assert received_transfers[0] == ReceiveTransferDirect(
        identifier,
        amount,
        token_address,
        app0.raiden.address,
    )
def test_target_log_directransfer_message(
        raiden_chain,
        token_addresses,
        deposit):

    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 21

    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app1_state_changes = get_all_state_changes(app1.raiden.transaction_log)
    received_transfers = [
        state_change
        for _, state_change in app1_state_changes
        if isinstance(state_change, ReceiveTransferDirect)
    ]
    assert received_transfers[0] == ReceiveTransferDirect(
        identifier,
        amount,
        token_address,
        app0.raiden.address,
    )
def test_initiator_log_directransfer_action(
        raiden_chain,
        token_addresses,
        deposit):
    """ The action that start a direct transfer must be logged in the WAL. """

    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 13

    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app0_state_changes = get_all_state_changes(app0.raiden.transaction_log)
    direct_transfers = [
        state_change
        for _, state_change in app0_state_changes
        if isinstance(state_change, ActionTransferDirect)
    ]
    assert direct_transfers[0] == ActionTransferDirect(
        identifier,
        amount,
        token_address,
        app1.raiden.address,
    )
def test_initiator_log_directransfer_action(
        raiden_chain,
        token_addresses,
        deposit):
    """ The action that start a direct transfer must be logged in the WAL. """

    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 13

    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app0_state_changes = get_all_state_changes(app0.raiden.transaction_log)
    direct_transfers = [
        state_change
        for _, state_change in app0_state_changes
        if isinstance(state_change, ActionTransferDirect)
    ]
    assert direct_transfers[0] == ActionTransferDirect(
        identifier,
        amount,
        token_address,
        app1.raiden.address,
    )
示例#5
0
def test_settlement(raiden_network, settle_timeout, reveal_timeout):
    alice_app, bob_app = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    setup_messages_cb()

    alice_graph = alice_app.raiden.channelgraphs.values()[0]
    bob_graph = bob_app.raiden.channelgraphs.values()[0]
    assert alice_graph.token_address == bob_graph.token_address

    alice_bob_channel = alice_graph.partneraddress_channel[
        bob_app.raiden.address]
    bob_alice_channel = bob_graph.partneraddress_channel[
        alice_app.raiden.address]

    alice_deposit = alice_bob_channel.balance
    bob_deposit = bob_alice_channel.balance

    token = alice_app.raiden.chain.token(alice_bob_channel.token_address)

    alice_balance = token.balance_of(alice_app.raiden.address)
    bob_balance = token.balance_of(bob_app.raiden.address)

    alice_chain = alice_app.raiden.chain

    alice_to_bob_amount = 10
    expiration = alice_app.raiden.chain.block_number() + reveal_timeout + 1
    secret = 'secretsecretsecretsecretsecretse'
    hashlock = sha3(secret)

    assert bob_app.raiden.address in alice_graph.partneraddress_channel

    nettingaddress0 = alice_bob_channel.external_state.netting_channel.address
    nettingaddress1 = bob_alice_channel.external_state.netting_channel.address
    assert nettingaddress0 == nettingaddress1

    identifier = 1
    fee = 0
    transfermessage = alice_bob_channel.create_mediatedtransfer(
        alice_app.raiden.get_block_number(),
        alice_app.raiden.address,
        bob_app.raiden.address,
        fee,
        alice_to_bob_amount,
        identifier,
        expiration,
        hashlock,
    )
    alice_app.raiden.sign(transfermessage)
    alice_bob_channel.register_transfer(
        alice_app.raiden.get_block_number(),
        transfermessage,
    )
    bob_alice_channel.register_transfer(
        bob_app.raiden.get_block_number(),
        transfermessage,
    )

    assert_synched_channels(
        alice_bob_channel,
        alice_deposit,
        [],
        bob_alice_channel,
        bob_deposit,
        [transfermessage.lock],
    )

    # At this point we are assuming the following:
    #
    #    A -> B MediatedTransfer
    #    B -> A SecretRequest
    #    A -> B RevealSecret
    #    - protocol didn't continue
    #
    # B knowns the secret but doesn't have an updated balance proof, B needs to
    # call settle.

    # get proof, that locked transfermessage was in merkle tree, with locked.root
    lock = bob_alice_channel.our_state.balance_proof.get_lock_by_hashlock(
        hashlock)
    assert sha3(secret) == hashlock
    unlock_proof = bob_alice_channel.our_state.balance_proof.compute_proof_for_lock(
        secret, lock)

    root = bob_alice_channel.our_state.balance_proof.merkleroot_for_unclaimed()

    assert check_proof(
        unlock_proof.merkle_proof,
        root,
        sha3(transfermessage.lock.as_bytes),
    )
    assert unlock_proof.lock_encoded == transfermessage.lock.as_bytes
    assert unlock_proof.secret == secret

    # a ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    bob_alice_channel.external_state.netting_channel.close(transfermessage)
    wait_until_block(alice_chain, alice_chain.block_number() + 1)

    assert alice_bob_channel.external_state.close_event.wait(timeout=15)
    assert bob_alice_channel.external_state.close_event.wait(timeout=15)

    assert alice_bob_channel.external_state.closed_block != 0
    assert bob_alice_channel.external_state.closed_block != 0
    assert alice_bob_channel.external_state.settled_block == 0
    assert bob_alice_channel.external_state.settled_block == 0

    # unlock will not be called by Channel.channel_closed because we did not
    # register the secret
    assert lock.expiration > alice_app.raiden.chain.block_number()
    assert lock.hashlock == sha3(secret)

    bob_alice_channel.external_state.netting_channel.withdraw([unlock_proof])

    settle_expiration = alice_chain.block_number() + settle_timeout + 2
    wait_until_block(alice_chain, settle_expiration)

    assert alice_bob_channel.external_state.settle_event.wait(timeout=15)
    assert bob_alice_channel.external_state.settle_event.wait(timeout=15)
    # settle must be called by the apps triggered by the ChannelClose event,
    # and the channels must update it's state based on the ChannelSettled event
    assert alice_bob_channel.external_state.settled_block != 0
    assert bob_alice_channel.external_state.settled_block != 0

    address0 = alice_app.raiden.address
    address1 = bob_app.raiden.address

    alice_netted_balance = alice_balance + alice_deposit - alice_to_bob_amount
    bob_netted_balance = bob_balance + bob_deposit + alice_to_bob_amount

    assert token.balance_of(address0) == alice_netted_balance
    assert token.balance_of(address1) == bob_netted_balance

    # Now let's query the WAL to see if the state changes were logged as expected
    state_changes = [
        change[1]
        for change in get_all_state_changes(alice_app.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]

    state_change1 = state_changes[0]
    state_change2 = state_changes[1]
    state_change3 = state_changes[2]
    state_change4 = state_changes[3]

    assert isinstance(state_change1, ContractReceiveClosed)
    assert state_change1.channel_address == nettingaddress0
    assert state_change1.closing_address == bob_app.raiden.address
    assert state_change1.block_number == alice_bob_channel.external_state.closed_block

    # Can't be sure of the order in which we encounter the SecretReveal and the withdraw
    assert_secretreveal_or_withdraw(state_change2, secret, nettingaddress0,
                                    bob_app.raiden.address)
    assert_secretreveal_or_withdraw(state_change3, secret, nettingaddress0,
                                    bob_app.raiden.address)

    assert isinstance(state_change4, ContractReceiveSettled)
    assert state_change4.channel_address == nettingaddress0
    assert state_change4.block_number == bob_alice_channel.external_state.settled_block
示例#6
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, {})
def test_settlement(raiden_network, settle_timeout, reveal_timeout):
    alice_app, bob_app = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    setup_messages_cb()

    alice_graph = list(alice_app.raiden.token_to_channelgraph.values())[0]
    bob_graph = list(bob_app.raiden.token_to_channelgraph.values())[0]
    assert alice_graph.token_address == bob_graph.token_address

    alice_bob_channel = alice_graph.partneraddress_to_channel[bob_app.raiden.address]
    bob_alice_channel = bob_graph.partneraddress_to_channel[alice_app.raiden.address]

    alice_deposit = alice_bob_channel.balance
    bob_deposit = bob_alice_channel.balance

    token = alice_app.raiden.chain.token(alice_bob_channel.token_address)

    alice_balance = token.balance_of(alice_app.raiden.address)
    bob_balance = token.balance_of(bob_app.raiden.address)

    alice_chain = alice_app.raiden.chain

    alice_to_bob_amount = 10
    expiration = alice_app.raiden.chain.block_number() + reveal_timeout + 1
    secret = b'secretsecretsecretsecretsecretse'
    hashlock = sha3(secret)

    assert bob_app.raiden.address in alice_graph.partneraddress_to_channel

    nettingaddress0 = alice_bob_channel.external_state.netting_channel.address
    nettingaddress1 = bob_alice_channel.external_state.netting_channel.address
    assert nettingaddress0 == nettingaddress1

    identifier = 1
    fee = 0
    transfermessage = alice_bob_channel.create_mediatedtransfer(
        alice_app.raiden.address,
        bob_app.raiden.address,
        fee,
        alice_to_bob_amount,
        identifier,
        expiration,
        hashlock,
    )
    alice_app.raiden.sign(transfermessage)
    alice_bob_channel.register_transfer(
        alice_app.raiden.get_block_number(),
        transfermessage,
    )
    bob_alice_channel.register_transfer(
        bob_app.raiden.get_block_number(),
        transfermessage,
    )

    assert_synched_channels(
        alice_bob_channel, alice_deposit, [],
        bob_alice_channel, bob_deposit, [transfermessage.lock],
    )

    # At this point we are assuming the following:
    #
    #    A -> B MediatedTransfer
    #    B -> A SecretRequest
    #    A -> B RevealSecret
    #    - protocol didn't continue
    #
    # B knowns the secret but doesn't have an updated balance proof, B needs to
    # call settle.

    # get proof, that locked transfermessage was in merkle tree, with locked.root
    lock = bob_alice_channel.partner_state.get_lock_by_hashlock(hashlock)
    assert sha3(secret) == hashlock
    unlock_proof = bob_alice_channel.partner_state.compute_proof_for_lock(secret, lock)

    root = merkleroot(bob_alice_channel.partner_state.merkletree)

    assert validate_proof(
        unlock_proof.merkle_proof,
        root,
        sha3(transfermessage.lock.as_bytes),
    )
    assert unlock_proof.lock_encoded == transfermessage.lock.as_bytes
    assert unlock_proof.secret == secret

    # a ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    balance_proof = transfermessage.to_balanceproof()
    bob_alice_channel.external_state.close(balance_proof)
    wait_until_block(alice_chain, alice_chain.block_number() + 1)

    assert alice_bob_channel.external_state.close_event.wait(timeout=15)
    assert bob_alice_channel.external_state.close_event.wait(timeout=15)

    assert alice_bob_channel.external_state.closed_block != 0
    assert bob_alice_channel.external_state.closed_block != 0
    assert alice_bob_channel.external_state.settled_block == 0
    assert bob_alice_channel.external_state.settled_block == 0

    # unlock will not be called by Channel.channel_closed because we did not
    # register the secret
    assert lock.expiration > alice_app.raiden.chain.block_number()
    assert lock.hashlock == sha3(secret)

    bob_alice_channel.external_state.netting_channel.withdraw([unlock_proof])

    settle_expiration = alice_chain.block_number() + settle_timeout + 2
    wait_until_block(alice_chain, settle_expiration)

    assert alice_bob_channel.external_state.settle_event.wait(timeout=15)
    assert bob_alice_channel.external_state.settle_event.wait(timeout=15)
    # settle must be called by the apps triggered by the ChannelClose event,
    # and the channels must update it's state based on the ChannelSettled event
    assert alice_bob_channel.external_state.settled_block != 0
    assert bob_alice_channel.external_state.settled_block != 0

    address0 = alice_app.raiden.address
    address1 = bob_app.raiden.address

    alice_netted_balance = alice_balance + alice_deposit - alice_to_bob_amount
    bob_netted_balance = bob_balance + bob_deposit + alice_to_bob_amount

    assert token.balance_of(address0) == alice_netted_balance
    assert token.balance_of(address1) == bob_netted_balance

    # Now let's query the WAL to see if the state changes were logged as expected
    state_changes = [
        change[1] for change in get_all_state_changes(alice_app.raiden.transaction_log)
        if not isinstance(change[1], Block)
    ]

    assert must_contain_entry(state_changes, ContractReceiveClosed, {
        'channel_address': nettingaddress0,
        'closing_address': bob_app.raiden.address,
        'block_number': alice_bob_channel.external_state.closed_block,
    })

    assert must_contain_entry(state_changes, ReceiveSecretReveal, {
        'secret': secret,
        'sender': bob_app.raiden.address,
    })

    assert must_contain_entry(state_changes, ContractReceiveWithdraw, {
        'channel_address': nettingaddress0,
        'secret': secret,
        'receiver': bob_app.raiden.address,
    })

    assert must_contain_entry(state_changes, ContractReceiveSettled, {
        'channel_address': nettingaddress0,
        'block_number': bob_alice_channel.external_state.settled_block,
    })
示例#8
0
文件: test_e2e.py 项目: timxor/raiden
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
示例#9
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, {})