示例#1
0
def test_event_transfer_received_success(token_addresses, raiden_chain):
    app0, app1, app2, receiver_app = raiden_chain
    token_address = token_addresses[0]

    expected = dict()

    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            receiver_app.raiden.address,
        )
        transfer_event.wait(timeout=20)
        expected[app.raiden.address] = amount

    # sleep is for the receiver's node to have time to process all events
    gevent.sleep(1)
    events = receiver_app.raiden.wal.storage.get_events_by_block(0, 'latest')
    events = [e[1] for e in events]

    assert must_contain_entry(events, EventTransferReceivedSuccess, {
        'amount': 1,
        'initiator': app0.raiden.address
    })
    assert must_contain_entry(events, EventTransferReceivedSuccess, {
        'amount': 2,
        'initiator': app1.raiden.address
    })
    assert must_contain_entry(events, EventTransferReceivedSuccess, {
        'amount': 3,
        'initiator': app2.raiden.address
    })
def test_initiator_log_directransfer_success(raiden_chain, token_addresses,
                                             deposit):
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 7
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        identifier,
    )

    app0_all_events = app0.raiden.wal.storage.get_events()
    assert must_contain_entry(
        app0_all_events, EventPaymentSentSuccess, {
            'identifier': identifier,
            'amount': amount,
            'target': app1.raiden.address,
        })

    app1_all_events = app1.raiden.wal.storage.get_events()
    assert must_contain_entry(
        app1_all_events, EventPaymentReceivedSuccess, {
            'identifier': identifier,
            'amount': amount,
            'initiator': app0.raiden.address,
        })
示例#3
0
def pending_mediated_transfer(app_chain, token, amount, identifier):
    """ Nice to read shortcut to make a LockedTransfer where the secret is _not_ revealed.

    While the secret is not revealed all apps will be synchronized, meaning
    they are all going to receive the LockedTransfer message.
    Returns:
        The secret used to generate the LockedTransfer
    """
    # pylint: disable=too-many-locals

    if len(app_chain) < 2:
        raise ValueError(
            'Cannot make a LockedTransfer with less than two apps')

    target = app_chain[-1].raiden.address

    # Generate a secret
    initiator_channel = get_channelstate(app_chain[0], app_chain[1], token)
    address = initiator_channel.identifier
    nonce_int = channel.get_next_nonce(initiator_channel.our_state)
    nonce_bytes = nonce_int.to_bytes(2, 'big')
    secret = sha3(address + nonce_bytes)

    initiator_app = app_chain[0]
    init_initiator_statechange = initiator_init(
        initiator_app.raiden,
        identifier,
        amount,
        secret,
        initiator_app.raiden.default_registry.address,
        token,
        target,
    )
    events = initiator_app.raiden.wal.log_and_dispatch(
        init_initiator_statechange,
        initiator_app.raiden.get_block_number(),
    )
    send_transfermessage = must_contain_entry(events, SendLockedTransfer, {})
    transfermessage = LockedTransfer.from_event(send_transfermessage)
    initiator_app.raiden.sign(transfermessage)

    for mediator_app in app_chain[1:-1]:
        mediator_init_statechange = mediator_init(mediator_app.raiden,
                                                  transfermessage)
        events = mediator_app.raiden.wal.log_and_dispatch(
            mediator_init_statechange,
            mediator_app.raiden.get_block_number(),
        )
        send_transfermessage = must_contain_entry(events, SendLockedTransfer,
                                                  {})
        transfermessage = LockedTransfer.from_event(send_transfermessage)
        mediator_app.raiden.sign(transfermessage)

    target_app = app_chain[-1]
    mediator_init_statechange = target_init(target_app.raiden, transfermessage)
    events = target_app.raiden.wal.log_and_dispatch(
        mediator_init_statechange,
        target_app.raiden.get_block_number(),
    )
    return secret
示例#4
0
 def test_target_events():
     target_events = app2.raiden.wal.storage.get_events()
     return (
         must_contain_entry(target_events, SendSecretRequest, {}) and
         must_contain_entry(target_events, SendSecretReveal, {}) and
         must_contain_entry(target_events, EventUnlockClaimSuccess, {})
     )
示例#5
0
def test_raiden_service_callback_new_block(raiden_network):
    """ Regression test for: https://github.com/raiden-network/raiden/issues/2894 """
    app0 = raiden_network[0]

    app0.raiden.alarm.stop()
    target_block_num = app0.raiden.chain.block_number(
    ) + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS + 1
    wait_until_block(
        app0.raiden.chain,
        target_block_num,
    )

    latest_block = app0.raiden.chain.get_block(block_identifier='latest')
    app0.raiden._callback_new_block(latest_block=latest_block)
    target_block_num = latest_block['number']

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(app0_state_changes, Block, {
        'block_number':
        target_block_num - DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
    })
    assert not must_contain_entry(app0_state_changes, Block, {
        'block_number': target_block_num,
    })
示例#6
0
def pending_mediated_transfer(app_chain, token_network_identifier, amount, identifier):
    """ Nice to read shortcut to make a LockedTransfer where the secret is _not_ revealed.

    While the secret is not revealed all apps will be synchronized, meaning
    they are all going to receive the LockedTransfer message.
    Returns:
        The secret used to generate the LockedTransfer
    """
    # pylint: disable=too-many-locals

    if len(app_chain) < 2:
        raise ValueError('Cannot make a LockedTransfer with less than two apps')

    target = app_chain[-1].raiden.address

    # Generate a secret
    initiator_channel = views.get_channelstate_by_token_network_and_partner(
        views.state_from_app(app_chain[0]),
        token_network_identifier,
        app_chain[1].raiden.address,
    )
    address = initiator_channel.identifier
    nonce_int = channel.get_next_nonce(initiator_channel.our_state)
    nonce_bytes = nonce_int.to_bytes(2, 'big')
    secret = sha3(address + nonce_bytes)

    initiator_app = app_chain[0]
    init_initiator_statechange = initiator_init(
        initiator_app.raiden,
        identifier,
        amount,
        secret,
        token_network_identifier,
        target,
    )
    events = initiator_app.raiden.wal.log_and_dispatch(
        init_initiator_statechange,
        initiator_app.raiden.get_block_number(),
    )
    send_transfermessage = must_contain_entry(events, SendLockedTransfer, {})
    transfermessage = LockedTransfer.from_event(send_transfermessage)
    initiator_app.raiden.sign(transfermessage)

    for mediator_app in app_chain[1:-1]:
        mediator_init_statechange = mediator_init(mediator_app.raiden, transfermessage)
        events = mediator_app.raiden.wal.log_and_dispatch(
            mediator_init_statechange,
            mediator_app.raiden.get_block_number(),
        )
        send_transfermessage = must_contain_entry(events, SendLockedTransfer, {})
        transfermessage = LockedTransfer.from_event(send_transfermessage)
        mediator_app.raiden.sign(transfermessage)

    target_app = app_chain[-1]
    mediator_init_statechange = target_init(transfermessage)
    events = target_app.raiden.wal.log_and_dispatch(
        mediator_init_statechange,
        target_app.raiden.get_block_number(),
    )
    return secret
示例#7
0
def test_raiden_service_callback_new_block(raiden_network):
    """ Regression test for: https://github.com/raiden-network/raiden/issues/2894 """
    app0 = raiden_network[0]

    app0.raiden.alarm.stop()
    target_block_num = app0.raiden.chain.block_number() + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS + 1
    wait_until_block(
        app0.raiden.chain,
        target_block_num,
    )

    latest_block = app0.raiden.chain.get_block(block_identifier='latest')
    app0.raiden._callback_new_block(latest_block=latest_block)
    target_block_num = latest_block['number']

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(app0_state_changes, Block, {
        'block_number': target_block_num - DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
    })
    assert not must_contain_entry(app0_state_changes, Block, {
        'block_number': target_block_num,
    })
def test_locked_transfer_secret_registered_onchain(
        raiden_network,
        token_addresses,
        secret_registry_address,
):
    app0 = raiden_network[0]
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 1
    target = UNIT_TRANSFER_INITIATOR
    identifier = 1
    transfer_secret = sha3(target + b'1')

    secret_registry_proxy = app0.raiden.chain.secret_registry(
        secret_registry_address,
    )
    secret_registry_proxy.register_secret(transfer_secret)

    # Test that sending a transfer with a secret already registered on-chain fails
    with pytest.raises(RaidenUnrecoverableError):
        app0.raiden.start_mediated_transfer_with_secret(
            token_network_identifier,
            amount,
            target,
            identifier,
            transfer_secret,
        )

    expiration = 9999
    transfer = make_signed_transfer(
        amount,
        UNIT_TRANSFER_INITIATOR,
        app0.raiden.address,
        expiration,
        transfer_secret,
    )

    message_handler = MessageHandler()
    message_handler.handle_message_lockedtransfer(
        app0.raiden,
        transfer,
    )

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(0, 'latest')
    transfer_statechange_dispatched = (
        must_contain_entry(state_changes, ActionInitMediator, {}) or
        must_contain_entry(state_changes, ActionInitTarget, {})
    )
    assert not transfer_statechange_dispatched
示例#9
0
def test_settle_is_automatically_called(raiden_network, token_addresses, deposit):
    """Settle is automatically called by one of the nodes."""
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_settle(
        app0.raiden,
        registry_address,
        token_address,
        [channel_identifier],
        app0.raiden.alarm.sleep_time,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    channel_state = get_channelstate(app0, app1, token_network_identifier)
    assert channel_state.close_transaction.finished_block_number
    assert channel_state.settle_transaction.finished_block_number

    assert must_contain_entry(state_changes, ContractReceiveChannelClosed, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'closing_address': app1.raiden.address,
        'closed_block_number': channel_state.close_transaction.finished_block_number,
    })

    assert must_contain_entry(state_changes, ContractReceiveChannelSettled, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'settle_block_number': channel_state.settle_transaction.finished_block_number,
    })
示例#10
0
def test_settle_is_automatically_called(raiden_network, token_addresses, deposit):
    """Settle is automatically called by one of the nodes."""
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier

    # A ChannelClose event will be generated, this will be polled by both apps
    # and each must start a task for calling settle
    RaidenAPI(app1.raiden).channel_close(
        registry_address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_settle(
        app0.raiden,
        registry_address,
        token_address,
        [channel_identifier],
        app0.raiden.alarm.wait_time,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    channel_state = get_channelstate(app0, app1, token_network_identifier)
    assert channel_state.close_transaction.finished_block_number
    assert channel_state.settle_transaction.finished_block_number

    assert must_contain_entry(state_changes, ContractReceiveChannelClosed, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'closing_address': app1.raiden.address,
        'closed_block_number': channel_state.close_transaction.finished_block_number,
    })

    assert must_contain_entry(state_changes, ContractReceiveChannelSettled, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel_identifier,
        'settle_block_number': channel_state.settle_transaction.finished_block_number,
    })
示例#11
0
def test_channelstate_unlock():
    """The node must call unlock after the channel is settled"""
    our_model1, _ = create_model(70)
    partner_model1, privkey2 = create_model(100)
    channel_state = create_channel_from_models(our_model1, partner_model1)

    lock_amount = 10
    lock_expiration = 100
    lock_secret = sha3(b'test_channelstate_lockedtransfer_overspent')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    nonce = 1
    transferred_amount = 0
    receive_lockedtransfer = make_receive_transfer_mediated(
        channel_state,
        privkey2,
        nonce,
        transferred_amount,
        lock,
    )

    is_valid, _, msg = channel.handle_receive_lockedtransfer(
        channel_state,
        receive_lockedtransfer,
    )
    assert is_valid, msg

    channel.register_secret(channel_state, lock_secret, lock_secrethash)

    closed_block_number = lock_expiration - channel_state.reveal_timeout - 1
    close_state_change = ContractReceiveChannelClosed(
        channel_state.token_network_identifier,
        channel_state.identifier,
        partner_model1.participant_address,
        closed_block_number,
    )
    iteration = channel.handle_channel_closed(channel_state, close_state_change)
    assert not must_contain_entry(iteration.events, ContractSendChannelBatchUnlock, {})

    settle_block_number = lock_expiration + channel_state.reveal_timeout + 1
    settle_state_change = ContractReceiveChannelSettled(
        channel_state.token_network_identifier,
        channel_state.identifier,
        settle_block_number,
    )
    iteration = channel.handle_channel_settled(
        channel_state,
        settle_state_change,
        settle_block_number,
    )
    assert must_contain_entry(iteration.events, ContractSendChannelBatchUnlock, {})
示例#12
0
def test_locked_transfer_secret_registered_onchain(
        raiden_network,
        token_addresses,
        secret_registry_address,
):
    app0 = raiden_network[0]
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 1
    target = UNIT_TRANSFER_INITIATOR
    identifier = 1
    transfer_secret = sha3(target + b'1')

    secret_registry_proxy = app0.raiden.chain.secret_registry(
        secret_registry_address,
    )
    secret_registry_proxy.register_secret(transfer_secret)

    # Test that sending a transfer with a secret already registered on-chain fails
    with pytest.raises(RaidenUnrecoverableError):
        app0.raiden.start_mediated_transfer_with_secret(
            token_network_identifier,
            amount,
            target,
            identifier,
            transfer_secret,
        )

    expiration = 9999
    transfer = make_signed_transfer(
        amount,
        UNIT_TRANSFER_INITIATOR,
        app0.raiden.address,
        expiration,
        transfer_secret,
    )

    message_handler = MessageHandler()
    message_handler.handle_message_lockedtransfer(
        app0.raiden,
        transfer,
    )

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(0, 'latest')
    transfer_statechange_dispatched = (
        must_contain_entry(state_changes, ActionInitMediator, {}) or
        must_contain_entry(state_changes, ActionInitTarget, {})
    )
    assert not transfer_statechange_dispatched
 def test_mediator_events():
     mediator_blockevents = app1.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     mediator_events = [blocknumber_event[1] for blocknumber_event in mediator_blockevents]
     return (
         must_contain_entry(mediator_events, EventUnlockSuccess, {}) and
         must_contain_entry(mediator_events, EventUnlockClaimSuccess, {})
     )
 def test_initiator_events():
     initiator_blockevents = app0.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     initiator_events = [blocknumber_event[1] for blocknumber_event in initiator_blockevents]
     return (
         must_contain_entry(initiator_events, SendRevealSecret, {}) and
         must_contain_entry(initiator_events, EventUnlockSuccess, {})
     )
示例#15
0
 def test_initiator_events():
     initiator_blockevents = app0.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     initiator_events = [
         blocknumber_event[1] for blocknumber_event in initiator_blockevents
     ]
     return (must_contain_entry(initiator_events, SendRevealSecret, {}) and
             must_contain_entry(initiator_events, EventUnlockSuccess, {}))
示例#16
0
def test_regression_mediator_send_lock_expired_with_new_block():
    """ The mediator must send the lock expired, but it must **not** clear
    itself if it has not **received** the corresponding message.
    """
    pseudo_random_generator = random.Random()

    channels = factories.mediator_make_channel_pair()
    payer_transfer = factories.make_default_signed_transfer_for(
        channels[0],
        initiator=HOP1,
        expiration=30,
    )

    init_iteration = mediator.state_transition(
        mediator_state=None,
        state_change=factories.mediator_make_init_action(
            channels, payer_transfer),
        channelidentifiers_to_channels=channels.channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=5,
    )
    assert init_iteration.new_state is not None
    send_transfer = must_contain_entry(init_iteration.events,
                                       SendLockedTransfer, {})
    assert send_transfer

    transfer = send_transfer.transfer

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

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

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

    assert must_contain_entry(iteration.events, SendLockExpired, {
        'secrethash': transfer.lock.secrethash,
    })
    assert transfer.lock.secrethash not in channels[
        1].our_state.secrethashes_to_lockedlocks
示例#17
0
 def test_mediator_events():
     mediator_blockevents = app1.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     mediator_events = [
         blocknumber_event[1] for blocknumber_event in mediator_blockevents
     ]
     return (must_contain_entry(mediator_events, EventUnlockSuccess, {})
             and must_contain_entry(mediator_events,
                                    EventUnlockClaimSuccess, {}))
示例#18
0
 def test_target_events():
     target_blockevents = app2.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     target_events = [
         blocknumber_event[1] for blocknumber_event in target_blockevents
     ]
     return (must_contain_entry(target_events, SendSecretRequest, {})
             and must_contain_entry(target_events, SendRevealSecret, {}) and
             must_contain_entry(target_events, EventUnlockClaimSuccess, {}))
 def test_target_events():
     target_blockevents = app2.raiden.wal.storage.get_events_by_identifier(
         from_identifier=0,
         to_identifier='latest',
     )
     target_events = [blocknumber_event[1] for blocknumber_event in target_blockevents]
     return (
         must_contain_entry(target_events, SendSecretRequest, {}) and
         must_contain_entry(target_events, SendRevealSecret, {}) and
         must_contain_entry(target_events, EventUnlockClaimSuccess, {})
     )
def test_handle_offchain_secretreveal_after_lock_expired():
    """Test that getting the secret revealed after lock expiration for the
    target does not end up continuously emitting EventUnlockClaimFailed

    Target part for https://github.com/raiden-network/raiden/issues/3086
    """
    setup = make_target_state()

    lock_expiration = setup.new_state.transfer.lock.expiration
    lock_expiration_block_number = lock_expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2
    lock_expiration_block = Block(
        block_number=lock_expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=lock_expiration_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number,
    )
    state = iteration.new_state

    msg = 'At the expiration block we should get an EventUnlockClaimFailed'
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed,
                              {}), msg

    iteration = target.state_transition(
        target_state=state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, setup.initiator),
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    state = iteration.new_state

    next_block = Block(
        block_number=lock_expiration_block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=state,
        state_change=next_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    msg = 'At the next block we should not get the same event'
    assert not must_contain_entry(iteration.events, EventUnlockClaimFailed,
                                  {}), msg
示例#21
0
def test_handle_offchain_secretreveal_after_lock_expired():
    """Test that getting the secret revealed after lock expiration for the
    target does not end up continuously emitting EventUnlockClaimFailed

    Target part for https://github.com/raiden-network/raiden/issues/3086
    """
    setup = make_target_state()

    lock_expiration_block_number = channel.get_sender_expiration_threshold(
        setup.new_state.transfer.lock,
    )
    lock_expiration_block = Block(
        block_number=lock_expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=lock_expiration_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number,
    )
    state = iteration.new_state

    msg = 'At the expiration block we should get an EventUnlockClaimFailed'
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg

    iteration = target.state_transition(
        target_state=state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, setup.initiator),
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    state = iteration.new_state

    next_block = Block(
        block_number=lock_expiration_block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=state,
        state_change=next_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    msg = 'At the next block we should not get the same event'
    assert not must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg
def test_regression_mediator_send_lock_expired_with_new_block():
    """ The mediator must send the lock expired, but it must **not** clear
    itself if it has not **received** the corresponding message.
    """
    pseudo_random_generator = random.Random()

    channels = factories.mediator_make_channel_pair()
    payer_transfer = factories.make_signed_transfer_for(channels[0], LONG_EXPIRATION)

    init_iteration = mediator.state_transition(
        mediator_state=None,
        state_change=factories.mediator_make_init_action(channels, payer_transfer),
        channelidentifiers_to_channels=channels.channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=5,
    )
    assert init_iteration.new_state is not None
    send_transfer = must_contain_entry(init_iteration.events, SendLockedTransfer, {})
    assert send_transfer

    transfer = send_transfer.transfer

    block_expiration_number = channel.get_sender_expiration_threshold(transfer.lock)
    block = Block(
        block_number=block_expiration_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = mediator.state_transition(
        mediator_state=init_iteration.new_state,
        state_change=block,
        channelidentifiers_to_channels=channels.channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_expiration_number,
    )

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

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

    assert must_contain_entry(iteration.events, SendLockExpired, {
        'secrethash': transfer.lock.secrethash,
    })
    assert transfer.lock.secrethash not in channels[1].our_state.secrethashes_to_lockedlocks
def test_log_directransfer(raiden_chain, token_addresses, deposit):
    """The action that starts a direct transfer must be logged in the WAL."""
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]

    amount = int(deposit / 2.)
    identifier = 13

    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    # ActionTransferDirect
    assert must_contain_entry(
        app0_state_changes, ActionForTokenNetwork, {
            'token_network_identifier': token_address,
            'sub_state_change': {
                'identifier': identifier,
                'amount': amount,
                'receiver_address': app1.raiden.address,
            }
        })

    # ReceiveTransferDirect
    app1_state_changes = app1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    assert must_contain_entry(
        app1_state_changes, ActionForTokenNetwork, {
            'token_network_identifier': token_address,
            'sub_state_change': {
                'transfer_identifier': identifier,
                'balance_proof': {
                    'transferred_amount': amount,
                    'sender': app0.raiden.address,
                }
            }
        })
示例#24
0
def test_initiator_handle_contract_receive_secret_reveal():
    """ Initiator must unlock off-chain if the secret is revealed on-chain and
    the channel is open.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    message_identifier = message_identifier_from_prng(deepcopy(setup.prng))

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier
    assert events.must_contain_entry(iteration.events, SendBalanceProof, {
        'message_identifier': message_identifier,
        'payment_identifier': payment_identifier,
    })
示例#25
0
def test_initiator_handle_contract_receive_secret_reveal_expired():
    """ Initiator must *not* unlock off-chain if the secret is revealed
    on-chain *after* the lock expiration.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration + 1,
    )

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    assert events.must_contain_entry(iteration.events, SendBalanceProof, {}) is None
def test_initiator_handle_contract_receive_secret_reveal_expired():
    """ Initiator must *not* unlock off-chain if the secret is revealed
    on-chain *after* the lock expiration.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration + 1,
    )

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    assert events.must_contain_entry(iteration.events, SendBalanceProof,
                                     {}) is None
def test_initiator_handle_contract_receive_secret_reveal():
    """ Initiator must unlock off-chain if the secret is revealed on-chain and
    the channel is open.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    message_identifier = message_identifier_from_prng(deepcopy(setup.prng))

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier
    assert events.must_contain_entry(
        iteration.events, SendBalanceProof, {
            'message_identifier': message_identifier,
            'payment_identifier': payment_identifier,
        })
def test_mediation(raiden_network, token_addresses, settle_timeout):
    # The network has the following topology:
    #
    # App1 <--> App0 <--> App2

    token_address = token_addresses[0]
    app0, app1, app2 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    identifier = 1
    amount = 1
    async_result = app1.raiden.mediated_transfer_async(
        token_address,
        amount,
        app2.raiden.address,
        identifier,
    )
    assert async_result.wait()

    mediator_chain = app0.raiden.chain
    settle_expiration = mediator_chain.block_number() + settle_timeout + 1
    wait_until_block(mediator_chain, settle_expiration)

    # context switch needed for tester to process the EventWithdrawSuccess
    gevent.sleep(1)

    app0_events = [
        event.event_object
        for event in get_all_state_events(app0.raiden.transaction_log)
    ]
    assert must_contain_entry(app0_events, EventWithdrawSuccess, {})
示例#29
0
def test_target_lock_is_expired_if_secret_is_not_registered_onchain():
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

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

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

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

    init = ActionInitTarget(
        from_route,
        from_transfer,
    )

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

    secret_reveal_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET,
                                         from_channel.partner_state.address),
        channel_state=from_channel,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    expired_block_number = from_transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS
    iteration = target.state_transition(
        target_state=secret_reveal_iteration.new_state,
        state_change=Block(expired_block_number, None, None),
        channel_state=from_channel,
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
示例#30
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    amount = 3
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    payment_network_identifier = factories.make_address()

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

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

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    state_change = ActionInitTarget(payment_network_identifier, from_route, from_transfer)
    iteration = target.handle_inittarget(state_change, from_channel, block_number)
    assert must_contain_entry(iteration.events, EventWithdrawFailed, {})
示例#31
0
def test_receive_directdtransfer_before_deposit():
    """Regression test that ensures that we accept incoming direct transfers,
    even if we don't have any balance on the channel.
    """
    our_model1, _ = create_model(0)  # our deposit is 0
    partner_model1, privkey2 = create_model(100)
    channel_state = create_channel_from_models(our_model1, partner_model1)
    payment_network_identifier = factories.make_address()

    nonce = 1
    transferred_amount = 30
    receive_directtransfer = make_receive_transfer_direct(
        payment_network_identifier,
        channel_state,
        privkey2,
        nonce,
        transferred_amount,
    )

    # this node partner has enough balance, the transfer must be accepted
    iteration = channel.handle_receive_directtransfer(
        channel_state,
        receive_directtransfer,
    )
    assert must_contain_entry(iteration.events, EventTransferReceivedSuccess, {})
示例#32
0
def test_mediation(raiden_network, token_addresses, settle_timeout):
    # The network has the following topology:
    #
    # App1 <--> App0 <--> App2

    token_address = token_addresses[0]
    app0, app1, app2 = raiden_network  # pylint: disable=unbalanced-tuple-unpacking

    identifier = 1
    amount = 1
    async_result = app1.raiden.mediated_transfer_async(
        token_address,
        amount,
        app2.raiden.address,
        identifier,
    )
    assert async_result.wait()

    mediator_chain = app0.raiden.chain
    settle_expiration = mediator_chain.block_number() + settle_timeout + 1
    wait_until_block(mediator_chain, settle_expiration)

    # context switch needed for tester to process the EventWithdrawSuccess
    gevent.sleep(1)

    app0_events = [
        event.event_object
        for event in get_all_state_events(app0.raiden.transaction_log)
    ]
    assert must_contain_entry(app0_events, EventWithdrawSuccess, {})
示例#33
0
def test_events_for_onchain_secretreveal():
    """ Secret must be registered on-chain when the unsafe region is reached and
    the secret is known.
    """
    block_number = 10
    expiration = block_number + 30

    channels = make_channel_set([channel_properties])
    from_transfer = make_target_transfer(channels[0], expiration=expiration)

    channel.handle_receive_lockedtransfer(channels[0], from_transfer)

    channel.register_offchain_secret(channels[0], UNIT_SECRET, UNIT_SECRETHASH)

    safe_to_wait = expiration - channels[0].reveal_timeout - 1
    unsafe_to_wait = expiration - channels[0].reveal_timeout

    state = TargetTransferState(channels.get_route(0), from_transfer)
    events = target.events_for_onchain_secretreveal(state, channels[0], safe_to_wait)
    assert not events

    events = target.events_for_onchain_secretreveal(state, channels[0], unsafe_to_wait)

    msg = 'when its not safe to wait, the contract send must be emitted'
    assert must_contain_entry(events, ContractSendSecretReveal, {'secret': UNIT_SECRET}), msg

    msg = 'second call must not emit ContractSendSecretReveal again'
    assert not target.events_for_onchain_secretreveal(state, channels[0], unsafe_to_wait), msg
示例#34
0
def test_channelstate_directtransfer_overspent():
    """Receiving a direct transfer with an amount large than distributable must
    be ignored.
    """
    our_model1, _ = create_model(70)
    partner_model1, privkey2 = create_model(100)
    channel_state = create_channel_from_models(our_model1, partner_model1)

    distributable = channel.get_distributable(channel_state.partner_state, channel_state.our_state)

    nonce = 1
    transferred_amount = distributable + 1
    receive_lockedtransfer = make_receive_transfer_direct(
        channel_state,
        privkey2,
        nonce,
        transferred_amount,
    )

    is_valid, _ = channel.is_valid_directtransfer(
        receive_lockedtransfer,
        channel_state,
        channel_state.partner_state,
        channel_state.our_state,
    )
    assert not is_valid, 'message is invalid because it is spending more than the distributable'

    iteration = channel.handle_receive_directtransfer(
        channel_state,
        receive_lockedtransfer,
    )

    assert must_contain_entry(iteration.events, EventTransferReceivedInvalidDirectTransfer, {})
    assert_partner_state(channel_state.our_state, channel_state.partner_state, our_model1)
    assert_partner_state(channel_state.partner_state, channel_state.our_state, partner_model1)
示例#35
0
def test_initiator_handle_contract_receive_secret_reveal():
    """ Initiator must unlock off-chain if the secret is revealed on-chain and
    the channel is open.
    """
    amount = UNIT_TRANSFER_AMOUNT * 2

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

    channel_map = {
        channel1.identifier: channel1,
    }

    available_routes = [
        factories.route_from_channel(channel1),
    ]

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

    transfer = current_state.initiator.transfer

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

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    message_identifier = message_identifier_from_prng(
        deepcopy(pseudo_random_generator))

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
    )

    assert events.must_contain_entry(
        iteration.events, SendBalanceProof, {
            'message_identifier':
            message_identifier,
            'payment_identifier':
            current_state.initiator.transfer_description.payment_identifier,
        })
def test_log_directransfer(raiden_chain, token_addresses, deposit):
    """The action that starts a direct transfer must be logged in the WAL."""
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    amount = int(deposit / 2.)
    payment_identifier = 13

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        payment_identifier,
    )

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(
        app0_state_changes, ActionTransferDirect, {
            'token_network_identifier': token_network_identifier,
            'amount': amount,
            'receiver_address': app1.raiden.address,
        })

    app1_state_changes = app1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    assert must_contain_entry(
        app1_state_changes, ReceiveTransferDirect, {
            'token_network_identifier': token_network_identifier,
            'payment_identifier': payment_identifier,
            'balance_proof': {
                'transferred_amount': amount,
                'sender': app0.raiden.address,
            },
        })
示例#37
0
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    amount = 3
    block_number = 1
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    pseudo_random_generator = random.Random()

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

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

    state_change = ActionInitTarget(
        from_route,
        from_transfer,
    )

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

    assert must_contain_entry(
        iteration.events, SendSecretRequest, {
            'payment_identifier': from_transfer.payment_identifier,
            'amount': from_transfer.lock.amount,
            'secrethash': from_transfer.lock.secrethash,
            'recipient': initiator,
        })
    assert must_contain_entry(iteration.events, SendProcessed, {})
示例#38
0
 def test_events(amount, address):
     return must_contain_entry(
         receiver_app.raiden.wal.storage.get_events(),
         EventPaymentReceivedSuccess,
         {
             'amount': amount,
             'initiator': address
         },
     )
def test_log_directransfer(raiden_chain, token_addresses, deposit):
    """The action that starts a direct transfer must be logged in the WAL."""
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    amount = int(deposit / 2.)
    payment_identifier = 13

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        payment_identifier,
    )

    app0_state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(app0_state_changes, ActionTransferDirect, {
        'token_network_identifier': token_network_identifier,
        'amount': amount,
        'receiver_address': app1.raiden.address,
    })

    app1_state_changes = app1.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    assert must_contain_entry(app1_state_changes, ReceiveTransferDirect, {
        'token_network_identifier': token_network_identifier,
        'payment_identifier': payment_identifier,
        'balance_proof': {
            'transferred_amount': amount,
            'sender': app0.raiden.address,
        },
    })
示例#40
0
 def test_events(amount, address):
     events = receiver_app.raiden.wal.storage.get_events_by_block(
         0, 'latest')
     events = [e[1] for e in events]
     return must_contain_entry(
         events,
         EventPaymentReceivedSuccess,
         {
             'amount': amount,
             'initiator': address
         },
     )
示例#41
0
def test_initiator_handle_contract_receive_after_channel_closed():
    """ Initiator must accept on-chain secret reveal if the channel is closed.
    However, the off-chain unlock must not be done!

    This will happen because secrets are registered after a channel is closed,
    during the settlement window.
    """
    block_number = 10
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=block_number)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    channel_closed = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=factories.make_address(),
        token_network_identifier=setup.channel.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        block_number=block_number,
    )

    channel_close_transition = channel.state_transition(
        channel_state=setup.channel,
        state_change=channel_closed,
        pseudo_random_generator=setup.prng,
        block_number=block_number,
    )
    channel_state = channel_close_transition.new_state

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    channel_map = {
        channel_state.identifier: channel_state,
    }
    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=setup.prng,
    )
    secrethash = setup.current_state.initiator.transfer_description.secrethash
    assert secrethash in channel_state.our_state.secrethashes_to_onchain_unlockedlocks

    msg = 'The channel is closed already, the balance proof must not be sent off-chain'
    assert not events.must_contain_entry(iteration.events, SendBalanceProof,
                                         {}), msg
def test_initiator_log_directransfer_success(raiden_chain, token_addresses, deposit):
    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 7
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    direct_transfer(
        app0,
        app1,
        token_network_identifier,
        amount,
        identifier,
    )

    app0_events = app0.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    app0_all_events = [event for _, event in app0_events]
    assert must_contain_entry(app0_all_events, EventTransferSentSuccess, {
        'identifier': identifier,
        'amount': amount,
        'target': app1.raiden.address,
    })

    app1_state_events = app1.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    app1_all_events = [event for _, event in app1_state_events]
    assert must_contain_entry(app1_all_events, EventTransferReceivedSuccess, {
        'identifier': identifier,
        'amount': amount,
        'initiator': app0.raiden.address,
    })
示例#43
0
def test_initiator_handle_contract_receive_after_channel_closed():
    """ Initiator must accept on-chain secret reveal if the channel is closed.
    However, the off-chain unlock must not be done!

    This will happen because secrets are registered after a channel is closed,
    during the settlement window.
    """
    block_number = 10
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=block_number)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    channel_closed = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=factories.make_address(),
        token_network_identifier=setup.channel.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        block_number=block_number,
    )

    channel_close_transition = channel.state_transition(
        channel_state=setup.channel,
        state_change=channel_closed,
        pseudo_random_generator=setup.prng,
        block_number=block_number,
    )
    channel_state = channel_close_transition.new_state

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    channel_map = {
        channel_state.identifier: channel_state,
    }
    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=setup.prng,
    )
    secrethash = setup.current_state.initiator.transfer_description.secrethash
    assert secrethash in channel_state.our_state.secrethashes_to_onchain_unlockedlocks

    msg = 'The channel is closed already, the balance proof must not be sent off-chain'
    assert not events.must_contain_entry(iteration.events, SendBalanceProof, {}), msg
示例#44
0
def wait_for_batch_unlock(app, channel_id, token_network_id):
    unlock_event = None
    while not unlock_event:
        gevent.sleep(1)

        state_changes = app.raiden.wal.storage.get_statechanges_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )

        unlock_event = must_contain_entry(state_changes, ContractReceiveChannelBatchUnlock, {
            'channel_identifier': channel_id,
            'token_network_identifier': token_network_id,
        })
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])

    transfer_properties = LockedTransferSignedStateProperties(
        transfer=LockedTransferProperties(
            amount=channels[0].partner_state.contract_balance,
            expiration=channels[0].reveal_timeout + block_number + 1,
            balance_proof=BalanceProofProperties(
                channel_identifier=channels[0].identifier,
                token_network_identifier=channels[0].token_network_identifier,
                transferred_amount=0,
                locked_amount=channels[0].partner_state.contract_balance,
            ),
        ), )
    from_transfer = create(transfer_properties)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)

    iteration = target.handle_inittarget(
        state_change,
        channels[0],
        pseudo_random_generator,
        block_number,
    )

    assert must_contain_entry(
        iteration.events, SendSecretRequest, {
            'payment_identifier': from_transfer.payment_identifier,
            'amount': from_transfer.lock.amount,
            'secrethash': from_transfer.lock.secrethash,
            'recipient': UNIT_TRANSFER_INITIATOR,
        })
    assert must_contain_entry(iteration.events, SendProcessed, {})
示例#46
0
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])

    transfer_properties = LockedTransferSignedStateProperties(
        transfer=LockedTransferProperties(
            amount=channels[0].partner_state.contract_balance,
            expiration=channels[0].reveal_timeout + block_number + 1,
            balance_proof=BalanceProofProperties(
                channel_identifier=channels[0].identifier,
                token_network_identifier=channels[0].token_network_identifier,
                transferred_amount=0,
                locked_amount=channels[0].partner_state.contract_balance,
            ),
        ),
    )
    from_transfer = create(transfer_properties)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)

    iteration = target.handle_inittarget(
        state_change,
        channels[0],
        pseudo_random_generator,
        block_number,
    )

    assert must_contain_entry(iteration.events, SendSecretRequest, {
        'payment_identifier': from_transfer.payment_identifier,
        'amount': from_transfer.lock.amount,
        'secrethash': from_transfer.lock.secrethash,
        'recipient': UNIT_TRANSFER_INITIATOR,
    })
    assert must_contain_entry(iteration.events, SendProcessed, {})
示例#47
0
def test_mediated_transfer_events(raiden_network, token_addresses,
                                  network_wait):
    network_wait *= 1.4
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    node_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        node_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait,
    )

    initiator_blockevents = app0.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    initiator_events = [
        blocknumber_event[1] for blocknumber_event in initiator_blockevents
    ]
    assert must_contain_entry(initiator_events, SendRevealSecret, {})
    assert must_contain_entry(initiator_events, EventUnlockSuccess, {})

    mediator_blockevents = app1.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    mediator_events = [
        blocknumber_event[1] for blocknumber_event in mediator_blockevents
    ]
    assert must_contain_entry(mediator_events, EventUnlockSuccess, {})
    assert must_contain_entry(mediator_events, EventUnlockClaimSuccess, {})

    target_blockevents = app2.raiden.wal.storage.get_events_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )
    target_events = [
        blocknumber_event[1] for blocknumber_event in target_blockevents
    ]
    assert must_contain_entry(target_events, SendSecretRequest, {})
    assert must_contain_entry(target_events, SendRevealSecret, {})
    assert must_contain_entry(target_events, EventUnlockClaimSuccess, {})
示例#48
0
def wait_for_batch_unlock(app, token_network_id, participant, partner):
    unlock_event = None
    while not unlock_event:
        gevent.sleep(1)

        state_changes = app.raiden.wal.storage.get_statechanges_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )

        unlock_event = must_contain_entry(state_changes, ContractReceiveChannelBatchUnlock, {
            'token_network_identifier': token_network_id,
            'participant': participant,
            'partner': partner,
        })
示例#49
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses, transport_protocol):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token,
    )
    transfer = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    event = must_contain_entry(
        app1.raiden.wal.storage.get_events(),
        SendSecretReveal,
        {},
    )
    assert event

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(
        message_identifier,
        event.secret,
    )
    app2.raiden.sign(reveal_secret)

    if transport_protocol is TransportProtocol.UDP:
        reveal_data = reveal_secret.encode()
        host_port = None
        app1.raiden.transport.receive(reveal_data, host_port)
    elif transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError('Unknown TransportProtocol')
示例#50
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])
    expiration = channels[0].reveal_timeout + block_number + 1
    from_transfer = make_target_transfer(channels[0], expiration=expiration)

    channel.handle_receive_lockedtransfer(channels[0], from_transfer)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)
    iteration = target.handle_inittarget(
        state_change,
        channels[0],
        pseudo_random_generator,
        block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
示例#51
0
def test_handle_offchain_secretreveal():
    setup = setup_initiator_tests()

    secret_reveal = ReceiveSecretReveal(
        secret=UNIT_SECRET,
        sender=setup.channel.partner_state.address,
    )
    message_identifier = message_identifier_from_prng(deepcopy(setup.prng))
    iteration = initiator.handle_offchain_secretreveal(
        initiator_state=setup.current_state.initiator,
        state_change=secret_reveal,
        channel_state=setup.channel,
        pseudo_random_generator=setup.prng,
    )

    payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier
    assert events.must_contain_entry(iteration.events, SendBalanceProof, {
        'message_identifier': message_identifier,
        'payment_identifier': payment_identifier,
    })
示例#52
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    amount = 3
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    pseudo_random_generator = random.Random()

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

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

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    state_change = ActionInitTarget(from_route, from_transfer)
    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
示例#53
0
def test_initiator_lock_expired_must_not_be_sent_if_channel_is_closed():
    """ If the channel is closed there is no rason to send balance proofs
    off-chain, so a remove expired lock must not be sent when the channel is
    closed.
    """
    block_number = 10
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2, block_number=block_number)

    channel_closed = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=factories.make_address(),
        token_network_identifier=setup.channel.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        block_number=block_number,
    )
    channel_close_transition = channel.state_transition(
        channel_state=setup.channel,
        state_change=channel_closed,
        pseudo_random_generator=setup.prng,
        block_number=block_number,
    )
    channel_state = channel_close_transition.new_state

    expiration_block_number = channel.get_sender_expiration_threshold(setup.lock)
    block = Block(
        block_number=expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    channel_map = {channel_state.identifier: channel_state}
    iteration = initiator_manager.state_transition(
        setup.current_state,
        block,
        channel_map,
        setup.prng,
        expiration_block_number,
    )
    assert events.must_contain_entry(iteration.events, SendLockExpired, {}) is None
示例#54
0
def test_target_lock_is_expired_if_secret_is_not_registered_onchain():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    from_transfer = make_target_transfer(channels[0], amount=lock_amount, block_number=1)

    init = ActionInitTarget(channels.get_route(0), from_transfer)

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is not None

    secret_reveal_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, channels[0].partner_state.address),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    expired_block_number = channel.get_receiver_expiration_threshold(from_transfer.lock)
    iteration = target.state_transition(
        target_state=secret_reveal_iteration.new_state,
        state_change=Block(expired_block_number, None, None),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
 def has_initiator_events():
     initiator_events = app0.raiden.wal.storage.get_events()
     return must_contain_entry(initiator_events, SendLockedTransfer, {})
示例#56
0
def test_target_receive_lock_expired():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    expiration = block_number + channels[0].settle_timeout - channels[0].reveal_timeout

    from_transfer = make_target_transfer(
        channels[0],
        amount=lock_amount,
        block_number=block_number,
    )

    init = ActionInitTarget(channels.get_route(0), from_transfer)

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is not None
    assert init_transition.new_state.route == channels.get_route(0)
    assert init_transition.new_state.transfer == from_transfer

    balance_proof = create(BalanceProofSignedStateProperties(
        balance_proof=BalanceProofProperties(
            nonce=2,
            transferred_amount=from_transfer.balance_proof.transferred_amount,
            locked_amount=0,
            token_network_identifier=from_transfer.balance_proof.token_network_identifier,
            channel_identifier=channels[0].identifier,
        ),
        message_hash=from_transfer.lock.secrethash,
    ))

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

    block_before_confirmed_expiration = expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS - 1
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=lock_expired_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_before_confirmed_expiration,
    )
    assert not must_contain_entry(iteration.events, SendProcessed, {})

    block_lock_expired = block_before_confirmed_expiration + 1
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=lock_expired_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_lock_expired,
    )
    assert must_contain_entry(iteration.events, SendProcessed, {})
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,
    })
示例#58
0
def test_recovery_blockchain_events(
        raiden_network,
        number_of_nodes,
        deposit,
        token_addresses,
        network_wait,
        skip_if_not_udp,
):
    """ Close one of the two raiden apps that have a channel between them,
    have the counterparty close the channel and then make sure the restarted
    app sees the change
    """
    app0, app1 = raiden_network
    token_address = token_addresses[0]

    app0.raiden.stop()
    host_port = (
        app0.raiden.config['transport']['udp']['host'],
        app0.raiden.config['transport']['udp']['port'],
    )
    socket = server._udp_socket(host_port)

    new_transport = UDPTransport(
        app0.raiden.address,
        app0.discovery,
        socket,
        app0.raiden.transport.throttle_policy,
        app0.raiden.config['transport']['udp'],
    )

    app1_api = RaidenAPI(app1.raiden)
    app1_api.channel_close(
        registry_address=app0.raiden.default_registry.address,
        token_address=token_address,
        partner_address=app0.raiden.address,
    )

    app0.stop()

    import gevent
    gevent.sleep(1)

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        transport=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        discovery=app0.raiden.discovery,
    )

    del app0  # from here on the app0_restart should be used

    app0_restart.raiden.start()

    # wait for the nodes' healthcheck to update the network statuses
    waiting.wait_for_healthy(
        app0_restart.raiden,
        app1.raiden.address,
        network_wait,
    )
    waiting.wait_for_healthy(
        app1.raiden,
        app0_restart.raiden.address,
        network_wait,
    )
    restarted_state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier(
        0,
        'latest',
    )
    assert must_contain_entry(restarted_state_changes, ContractReceiveChannelClosed, {})
示例#59
0
def test_recovery_unhappy_case(
        raiden_network,
        number_of_nodes,
        deposit,
        token_addresses,
        network_wait,
        skip_if_not_udp,
        retry_timeout,
):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    # make a few transfers from app0 to app2
    amount = 1
    spent_amount = deposit - 2
    for _ in range(spent_amount):
        mediated_transfer(
            app0,
            app2,
            token_network_identifier,
            amount,
            timeout=network_wait * number_of_nodes,
        )

    app0.raiden.stop()
    host_port = (
        app0.raiden.config['transport']['udp']['host'],
        app0.raiden.config['transport']['udp']['port'],
    )
    socket = server._udp_socket(host_port)

    new_transport = UDPTransport(
        app0.raiden.address,
        app0.discovery,
        socket,
        app0.raiden.transport.throttle_policy,
        app0.raiden.config['transport']['udp'],
    )

    app0.stop()

    RaidenAPI(app1.raiden).channel_close(
        app1.raiden.default_registry.address,
        token_address,
        app0.raiden.address,
    )

    channel01 = views.get_channelstate_for(
        views.state_from_app(app1),
        app1.raiden.default_registry.address,
        token_address,
        app0.raiden.address,
    )

    waiting.wait_for_settle(
        app1.raiden,
        app1.raiden.default_registry.address,
        token_address,
        [channel01.identifier],
        retry_timeout,
    )

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    app0_restart = App(
        config=app0.config,
        chain=app0.raiden.chain,
        query_start_block=0,
        default_registry=app0.raiden.default_registry,
        default_secret_registry=app0.raiden.default_secret_registry,
        transport=new_transport,
        raiden_event_handler=raiden_event_handler,
        message_handler=message_handler,
        discovery=app0.raiden.discovery,
    )
    del app0  # from here on the app0_restart should be used
    app0_restart.start()

    state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier(
        from_identifier=0,
        to_identifier='latest',
    )

    assert must_contain_entry(state_changes, ContractReceiveChannelSettled, {
        'token_network_identifier': token_network_identifier,
        'channel_identifier': channel01.identifier,
    })