def test_locked_transfer_additional_hash_contains_route_metadata_hash():
    one_locked_transfer = factories.create(
        factories.LockedTransferProperties())
    route_metadata = factories.create(
        factories.RouteMetadataProperties(
            route=[factories.HOP2, factories.HOP1]))
    another_locked_transfer = factories.create(
        factories.LockedTransferProperties(metadata=factories.create(
            factories.MetadataProperties(routes=[route_metadata]))))

    assert (
        one_locked_transfer.message_hash !=
        another_locked_transfer.message_hash
    ), "LockedTransfers with different routes should have different message hashes"
Beispiel #2
0
def test_target_task_view():
    """Same as above for target tasks."""
    secret = factories.make_secret()
    transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(secret=secret), ))
    secrethash = transfer.lock.secrethash
    mediator = factories.make_address()
    mediator_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                address=mediator, balance=100), ))
    transfer_state = TargetTransferState(route=None,
                                         transfer=transfer,
                                         secret=secret)
    task = TargetTask(
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=mediator_channel.identifier,
        target_state=transfer_state,
    )
    payment_mapping = {secrethash: task}

    view = transfer_tasks_view(payment_mapping)

    assert len(view) == 1
    pending_transfer = view[0]
    assert pending_transfer.get('role') == 'target'
    assert pending_transfer.get('locked_amount') == str(
        transfer.balance_proof.locked_amount)
    assert pending_transfer.get('payment_identifier') == str(
        transfer.payment_identifier)
def test_mediated_transfer_calls_pfs(raiden_network, token_addresses):
    app0, = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    token_network_registry_address = app0.raiden.default_registry.address
    token_network_address = views.get_token_network_address_by_token_address(
        chain_state, token_network_registry_address, token_address)

    with patch("raiden.routing.query_paths",
               return_value=([], None)) as patched:

        app0.raiden.start_mediated_transfer_with_secret(
            token_network_address=token_network_address,
            amount=10,
            target=factories.HOP1,
            identifier=1,
            secret=b"1" * 32,
        )
        assert not patched.called

        # Setup PFS config
        app0.raiden.config["pfs_config"] = PFSConfig(
            info=PFSInfo(
                url="mock-address",
                chain_id=app0.raiden.rpc_client.chain_id,
                token_network_registry_address=token_network_registry_address,
                payment_address=factories.make_address(),
                message="",
                operator="",
                version="",
                price=TokenAmount(0),
            ),
            maximum_fee=TokenAmount(100),
            iou_timeout=BlockNumber(100),
            max_paths=5,
        )

        app0.raiden.start_mediated_transfer_with_secret(
            token_network_address=token_network_address,
            amount=11,
            target=factories.HOP2,
            identifier=2,
            secret=b"2" * 32,
        )
        assert patched.call_count == 1

        # Mediator should not re-query PFS
        locked_transfer = factories.create(
            factories.LockedTransferProperties(
                amount=TokenAmount(5),
                initiator=factories.HOP1,
                target=TargetAddress(factories.HOP2),
                sender=factories.HOP1,
                pkey=factories.HOP1_KEY,
                token=token_address,
                canonical_identifier=factories.make_canonical_identifier(
                    token_network_address=token_network_address),
            ))
        app0.raiden.mediate_mediated_transfer(locked_transfer)
        assert patched.call_count == 1
Beispiel #4
0
def make_from_route_from_counter(counter):
    from_channel = factories.make_channel(
        partner_balance=next(counter),
        partner_address=factories.HOP1,
        token_address=factories.make_address(),
        channel_identifier=next(counter),
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = factories.UNIT_REVEAL_TIMEOUT + 1

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                balance_proof=factories.BalanceProofProperties(
                    transferred_amount=0,
                    token_network_identifier=from_channel.
                    token_network_identifier,
                ),
                amount=1,
                expiration=expiration,
                secret=sha3(factories.make_secret(next(counter))),
                initiator=factories.make_address(),
                target=factories.make_address(),
                payment_identifier=next(counter),
            ),
            sender=factories.HOP1,
            pkey=factories.HOP1_KEY,
        ),
    )
    return from_route, from_transfer
def test_target_reject_keccak_empty_hash():
    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 = factories.make_signed_transfer_for(
        channels[0],
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                amount=lock_amount,
                target=channels.our_address(0),
                expiration=expiration,
                secret=EMPTY_HASH,
            ), ),
        allow_invalid=True,
    )

    init = ActionInitTarget(route=channels.get_route(0),
                            transfer=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 None
Beispiel #6
0
def test_channel_closed_must_clear_ordered_messages(chain_state,
                                                    token_network_state,
                                                    netting_channel_state):
    recipient = netting_channel_state.partner_state.address
    message_identifier = random.randint(0, 2**16)
    amount = 10

    queue_identifier = QueueIdentifier(
        recipient=recipient,
        canonical_identifier=netting_channel_state.canonical_identifier)

    # Regression test:
    # The code delivered_message handler worked only with a queue of one
    # element
    message = factories.create(
        factories.LockedTransferProperties(
            message_identifier=message_identifier,
            token=token_network_state.token_address,
            canonical_identifier=netting_channel_state.canonical_identifier,
            transferred_amount=amount,
            recipient=recipient,
        ))

    chain_state.queueids_to_queues[queue_identifier] = [message]

    closed = state_change.ContractReceiveChannelClosed(
        transaction_hash=EMPTY_HASH,
        transaction_from=recipient,
        canonical_identifier=netting_channel_state.canonical_identifier,
        block_number=1,
        block_hash=factories.make_block_hash(),
    )

    iteration = node.handle_state_change(chain_state, closed)
    assert queue_identifier not in iteration.new_state.queueids_to_queues
Beispiel #7
0
def run_test_locked_transfer_secret_registered_onchain(raiden_network,
                                                       token_addresses,
                                                       secret_registry_address,
                                                       retry_timeout):
    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 = factories.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(secret=transfer_secret)

    # Wait until our node has processed the block that the secret registration was mined at
    block_number = app0.raiden.get_block_number()
    wait_for_block(
        raiden=app0.raiden,
        block_number=block_number + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
        retry_timeout=retry_timeout,
    )

    # 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=token_network_identifier,
            amount=amount,
            fee=0,
            target=target,
            identifier=identifier,
            payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE,
            secret=transfer_secret,
        )

    # Test that receiving a transfer with a secret already registered on chain fails
    expiration = 9999
    locked_transfer = factories.create(
        factories.LockedTransferProperties(
            amount=amount,
            target=app0.raiden.address,
            expiration=expiration,
            secret=transfer_secret,
        ))

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

    state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier(
        0, "latest")
    transfer_statechange_dispatched = search_for_item(
        state_changes, ActionInitMediator, {}) or search_for_item(
            state_changes, ActionInitTarget, {})
    assert not transfer_statechange_dispatched
def test_locked_transfer_secret_registered_onchain(
    raiden_network, token_addresses, secret_registry_address, retry_timeout
):
    app0 = raiden_network[0]
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    token_network_registry_address = app0.raiden.default_registry.address
    token_network_address = views.get_token_network_address_by_token_address(
        chain_state, token_network_registry_address, token_address
    )

    amount = TokenAmount(1)
    target = factories.UNIT_TRANSFER_INITIATOR
    identifier = PaymentID(1)
    transfer_secret = make_secret()

    secret_registry_proxy = app0.raiden.proxy_manager.secret_registry(
        secret_registry_address, block_identifier=chain_state.block_hash
    )
    secret_registry_proxy.register_secret(secret=transfer_secret)

    # Wait until our node has processed the block that the secret registration was mined at
    block_number = app0.raiden.get_block_number()
    wait_for_block(
        raiden=app0.raiden,
        block_number=block_number + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
        retry_timeout=retry_timeout,
    )

    # 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_address=token_network_address,
            amount=amount,
            target=target,
            identifier=identifier,
            secret=transfer_secret,
        )

    # Test that receiving a transfer with a secret already registered on chain fails
    expiration = BlockExpiration(9999)
    locked_transfer = factories.create(
        factories.LockedTransferProperties(
            amount=amount,
            target=app0.raiden.address,
            expiration=expiration,
            secret=transfer_secret,
        )
    )

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

    state_changes = app0.raiden.wal.storage.get_statechanges_by_range(RANGE_ALL_STATE_CHANGES)
    transfer_statechange_dispatched = search_for_item(
        state_changes, ActionInitMediator, {}
    ) or search_for_item(state_changes, ActionInitTarget, {})
    assert not transfer_statechange_dispatched
def test_locked_transfer_with_metadata():
    locked_transfer = factories.create(factories.LockedTransferProperties())
    assert isinstance(locked_transfer, LockedTransfer)
    assert isinstance(locked_transfer.metadata, Metadata)

    # pylint: disable=E1101
    assert locked_transfer.metadata.routes[0].route == [
        factories.HOP1, factories.HOP2
    ]
def test_mediated_transfer_min_max(amount, payment_identifier, nonce,
                                   transferred_amount):
    mediated_transfer = factories.create(
        factories.LockedTransferProperties(
            amount=amount,
            payment_identifier=payment_identifier,
            nonce=nonce,
            transferred_amount=transferred_amount,
        ))
    mediated_transfer._data_to_sign(
    )  # Just test that packing works without exceptions.
Beispiel #11
0
def test_mediated_transfer_min_max(amount, payment_identifier, fee, nonce,
                                   transferred_amount):
    mediated_transfer = factories.create(
        factories.LockedTransferProperties(
            amount=amount,
            payment_identifier=payment_identifier,
            nonce=nonce,
            transferred_amount=transferred_amount,
            fee=fee,
        ))
    assert decode(mediated_transfer.encode()) == mediated_transfer
Beispiel #12
0
def run_test_mediated_transfer_calls_pfs(raiden_network, token_addresses):
    app0, = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_id = views.get_token_network_identifier_by_token_address(
        chain_state, payment_network_id, token_address)

    with patch("raiden.routing.query_paths",
               return_value=([], None)) as patched:

        app0.raiden.start_mediated_transfer_with_secret(
            token_network_identifier=token_network_id,
            amount=10,
            fee=0,
            target=factories.HOP1,
            identifier=1,
            payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE,
            secret=b"1" * 32,
        )
        assert not patched.called

        config_patch = dict(
            pathfinding_service_address="mock-address",
            pathfinding_eth_address=factories.make_checksum_address(),
        )

        with patch.dict(app0.raiden.config["services"], config_patch):
            app0.raiden.start_mediated_transfer_with_secret(
                token_network_identifier=token_network_id,
                amount=11,
                fee=0,
                target=factories.HOP2,
                identifier=2,
                payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE,
                secret=b"2" * 32,
            )
            assert patched.call_count == 1

            locked_transfer = factories.create(
                factories.LockedTransferProperties(
                    amount=TokenAmount(5),
                    initiator=factories.HOP1,
                    target=factories.HOP2,
                    sender=factories.HOP1,
                    pkey=factories.HOP1_KEY,
                    token=token_address,
                    canonical_identifier=factories.make_canonical_identifier(
                        token_network_address=token_network_id),
                ))
            app0.raiden.mediate_mediated_transfer(locked_transfer)
            assert patched.call_count == 2
def test_mediated_transfer_min_max(amount, payment_identifier, nonce, transferred_amount):
    mediated_transfer = factories.create(
        factories.LockedTransferProperties(
            amount=amount,
            payment_identifier=payment_identifier,
            nonce=nonce,
            transferred_amount=transferred_amount,
        )
    )

    mediated_transfer.sign(signer)
    data = JSONSerializer.serialize(mediated_transfer)
    assert JSONSerializer.deserialize(data) == mediated_transfer
def make_target_transfer(channel,
                         amount=None,
                         expiration=None,
                         initiator=None,
                         block_number=1):
    default_expiration = block_number + channel.settle_timeout - channel.reveal_timeout

    return factories.make_signed_transfer_for(
        channel,
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                amount=amount or channel.partner_state.contract_balance,
                expiration=expiration or default_expiration,
                initiator=initiator or UNIT_TRANSFER_INITIATOR,
                target=channel.our_state.address,
            ), ),
    )
Beispiel #15
0
def test_initiator_task_view():
    """Test transfer_tasks_view(), which is used to generate the output of the
    pending transfers API, with an initiator task.
    """
    channel_id = factories.UNIT_CHANNEL_ID
    secret = factories.make_secret()
    transfer = factories.create(
        factories.LockedTransferProperties(secret=secret))
    secrethash = transfer.lock.secrethash
    transfer_description = TransferDescriptionWithSecretState(
        payment_network_identifier=factories.UNIT_PAYMENT_NETWORK_IDENTIFIER,
        payment_identifier=transfer.payment_identifier,
        amount=transfer.balance_proof.locked_amount,
        allocated_fee=0,
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        initiator=transfer.initiator,
        target=transfer.target,
        secret=secret,
    )
    transfer_state = InitiatorTransferState(
        transfer_description=transfer_description,
        channel_identifier=channel_id,
        transfer=transfer,
        revealsecret=None,
    )
    payment_state = InitiatorPaymentState({secrethash: transfer_state})
    task = InitiatorTask(
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        manager_state=payment_state,
    )
    payment_mapping = {secrethash: task}

    view = transfer_tasks_view(payment_mapping)

    assert len(view) == 1
    pending_transfer = view[0]
    assert pending_transfer.get('role') == 'initiator'
    balance_proof = transfer.balance_proof
    assert pending_transfer.get('channel_identifier') == str(
        balance_proof.channel_identifier)
    assert pending_transfer.get('locked_amount') == str(
        balance_proof.locked_amount)
    assert pending_transfer.get('transferred_amount') == str(
        balance_proof.transferred_amount)
Beispiel #16
0
def test_changing_route_metadata_will_invalidate_lock_transfer_signature():
    one_locked_transfer = factories.create(
        factories.LockedTransferProperties(sender=ADDRESS, pkey=PRIVKEY))

    new_route_metadata = factories.create(
        factories.RouteMetadataProperties(
            route=[factories.HOP2, factories.HOP1]))

    new_metadata = factories.create(
        factories.Metadata(routes=[new_route_metadata]))

    assert ADDRESS == recover(one_locked_transfer._data_to_sign(),
                              one_locked_transfer.signature
                              ), "signature does not match signer address"

    one_locked_transfer.metadata = new_metadata

    assert ADDRESS != recover(
        one_locked_transfer._data_to_sign(), one_locked_transfer.signature
    ), "signature should not be valid after data being altered"
Beispiel #17
0
def test_mediated_transfer_invalid_values(invalid_values):
    for invalid_value in invalid_values:
        with pytest.raises(ValueError):
            factories.create(
                factories.LockedTransferProperties(**invalid_value))
Beispiel #18
0
def test_message_handler():
    """
    Test for MessageHandler.on_message and the different methods it dispatches into.
    Each of them results in a call to a RaidenService method, which is checked with a Mock.
    """

    our_address = factories.make_address()
    sender_privkey, sender = factories.make_privkey_address()
    signer = LocalSigner(sender_privkey)
    message_handler = MessageHandler()
    mock_raiden = Mock(
        address=our_address, default_secret_registry=Mock(is_secret_registered=lambda **_: False)
    )

    properties = factories.LockedTransferProperties(sender=sender, pkey=sender_privkey)
    locked_transfer = factories.create(properties)
    message_handler.on_message(mock_raiden, locked_transfer)
    assert_method_call(mock_raiden, "mediate_mediated_transfer", locked_transfer)

    locked_transfer_for_us = factories.create(factories.replace(properties, target=our_address))
    message_handler.on_message(mock_raiden, locked_transfer_for_us)
    assert_method_call(mock_raiden, "target_mediated_transfer", locked_transfer_for_us)

    mock_raiden.default_secret_registry.is_secret_registered = lambda **_: True
    message_handler.on_message(mock_raiden, locked_transfer)
    assert not mock_raiden.mediate_mediated_transfer.called
    assert not mock_raiden.target_mediated_transfer.called
    mock_raiden.default_secret_registry.is_secret_registered = lambda **_: False

    params = dict(
        payment_identifier=13, amount=14, expiration=15, secrethash=factories.UNIT_SECRETHASH
    )
    secret_request = SecretRequest(
        message_identifier=16, signature=factories.EMPTY_SIGNATURE, **params
    )
    secret_request.sign(signer)
    receive = ReceiveSecretRequest(sender=sender, **params)
    message_handler.on_message(mock_raiden, secret_request)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    secret = factories.make_secret()
    reveal_secret = RevealSecret(
        message_identifier=100, signature=factories.EMPTY_SIGNATURE, secret=secret
    )
    reveal_secret.sign(signer)
    receive = ReceiveSecretReveal(sender=sender, secret=secret)
    message_handler.on_message(mock_raiden, reveal_secret)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    properties: factories.UnlockProperties = factories.create_properties(
        factories.UnlockProperties()
    )
    unlock = factories.create(properties)
    unlock.sign(signer)
    balance_proof = factories.make_signed_balance_proof_from_unsigned(
        factories.create(properties.balance_proof), signer, unlock.message_hash
    )
    receive = ReceiveUnlock(
        message_identifier=properties.message_identifier,
        secret=properties.secret,
        balance_proof=balance_proof,
        sender=sender,
    )
    message_handler.on_message(mock_raiden, unlock)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    properties: factories.LockExpiredProperties = factories.create_properties(
        factories.LockExpiredProperties()
    )
    lock_expired = factories.create(properties)
    lock_expired.sign(signer)
    balance_proof = factories.make_signed_balance_proof_from_unsigned(
        factories.create(properties.balance_proof), signer, lock_expired.message_hash
    )
    receive = ReceiveLockExpired(
        balance_proof=balance_proof,
        message_identifier=properties.message_identifier,
        secrethash=properties.secrethash,  # pylint: disable=no-member
        sender=sender,
    )
    message_handler.on_message(mock_raiden, lock_expired)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    delivered = Delivered(delivered_message_identifier=1, signature=factories.EMPTY_SIGNATURE)
    delivered.sign(signer)
    receive = ReceiveDelivered(message_identifier=1, sender=sender)
    message_handler.on_message(mock_raiden, delivered)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])

    processed = Processed(message_identifier=42, signature=factories.EMPTY_SIGNATURE)
    processed.sign(signer)
    receive = ReceiveProcessed(message_identifier=42, sender=sender)
    message_handler.on_message(mock_raiden, processed)
    assert_method_call(mock_raiden, "handle_and_track_state_changes", [receive])
Beispiel #19
0
def test_encoding_and_decoding():
    message_factories = (
        factories.LockedTransferProperties(),
        factories.RefundTransferProperties(),
        factories.LockExpiredProperties(),
        factories.UnlockProperties(),
    )
    messages = [factories.create(factory) for factory in message_factories]

    # TODO Handle these with factories once #5091 is implemented
    messages.append(
        Delivered(
            delivered_message_identifier=factories.make_message_identifier(),
            signature=factories.make_signature(),
        ))
    messages.append(
        Processed(
            message_identifier=factories.make_message_identifier(),
            signature=factories.make_signature(),
        ))
    messages.append(
        RevealSecret(
            message_identifier=factories.make_message_identifier(),
            secret=factories.make_secret(),
            signature=factories.make_signature(),
        ))
    messages.append(
        SecretRequest(
            message_identifier=factories.make_message_identifier(),
            payment_identifier=factories.make_payment_id(),
            secrethash=factories.make_secret_hash(),
            amount=factories.make_token_amount(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawRequest(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawConfirmation(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        WithdrawExpired(
            message_identifier=factories.make_message_identifier(),
            chain_id=factories.make_chain_id(),
            token_network_address=factories.make_token_network_address(),
            channel_identifier=factories.make_channel_identifier(),
            participant=factories.make_address(),
            total_withdraw=factories.make_token_amount(),
            nonce=factories.make_nonce(),
            expiration=factories.make_block_number(),
            signature=factories.make_signature(),
        ))
    messages.append(
        PFSCapacityUpdate(
            canonical_identifier=factories.make_canonical_identifier(),
            updating_participant=factories.make_address(),
            other_participant=factories.make_address(),
            updating_nonce=factories.make_nonce(),
            other_nonce=factories.make_nonce(),
            updating_capacity=factories.make_token_amount(),
            other_capacity=factories.make_token_amount(),
            reveal_timeout=factories.make_uint64(),
            signature=factories.make_signature(),
        ))
    messages.append(
        PFSFeeUpdate(
            canonical_identifier=factories.make_canonical_identifier(),
            updating_participant=factories.make_address(),
            fee_schedule=factories.create(
                factories.FeeScheduleStateProperties()),
            timestamp=datetime.now(),
            signature=factories.make_signature(),
        ))
    messages.append(
        RequestMonitoring(
            reward_amount=factories.make_token_amount(),
            balance_proof=SignedBlindedBalanceProof.
            from_balance_proof_signed_state(
                factories.create(
                    factories.BalanceProofSignedStateProperties())),
            monitoring_service_contract_address=factories.make_address(),
            non_closing_participant=factories.make_address(),
            non_closing_signature=factories.make_signature(),
            signature=factories.make_signature(),
        ))

    for message in messages:
        serialized = MessageSerializer.serialize(message)
        deserialized = MessageSerializer.deserialize(serialized)
        assert deserialized == message
    ActionInitMediator,
    ReceiveLockExpired,
    ReceiveSecretReveal,
    ReceiveTransferRefund,
)
from raiden.transfer.state import (
    NODE_NETWORK_UNREACHABLE,
    balanceproof_from_envelope,
    message_identifier_from_prng,
)
from raiden.transfer.state_change import Block, ContractReceiveSecretReveal
from raiden.utils.signer import LocalSigner

LONG_EXPIRATION = factories.create_properties(
    factories.LockedTransferSignedStateProperties(
        transfer=factories.LockedTransferProperties(expiration=30), ))


def test_payer_enter_danger_zone_with_transfer_payed():
    """ A mediator may have paid the next hop (payee), and didn't get paid by
    the previous hop (payer).

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

    Issue: https://github.com/raiden-network/raiden/issues/1013
    """
    block_number = 5
    pseudo_random_generator = random.Random()

    channels = factories.mediator_make_channel_pair()
def test_mediated_transfer_calls_pfs(raiden_chain: List[App], token_addresses: List[TokenAddress]):
    app0, app1, app2 = raiden_chain
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    token_network_registry_address = app0.raiden.default_registry.address
    token_network_address = views.get_token_network_address_by_token_address(
        chain_state, token_network_registry_address, token_address
    )
    assert token_network_address, "Fixture token_addresses don't have correspoding token_network"

    with patch("raiden.routing.query_paths", return_value=([], None)) as patched:

        app0.raiden.start_mediated_transfer_with_secret(
            token_network_address=token_network_address,
            amount=PaymentAmount(10),
            target=TargetAddress(app1.raiden.address),
            identifier=PaymentID(1),
            secret=Secret(b"1" * 32),
        )
        assert not patched.called

        # Setup PFS config
        app0.raiden.config.pfs_config = PFSConfig(
            info=PFSInfo(
                url="mock-address",
                chain_id=app0.raiden.rpc_client.chain_id,
                token_network_registry_address=token_network_registry_address,
                user_deposit_address=factories.make_address(),
                payment_address=factories.make_address(),
                confirmed_block_number=chain_state.block_number,
                message="",
                operator="",
                version="",
                price=TokenAmount(0),
            ),
            maximum_fee=TokenAmount(100),
            iou_timeout=BlockTimeout(100),
            max_paths=5,
        )

        app0.raiden.start_mediated_transfer_with_secret(
            token_network_address=token_network_address,
            amount=PaymentAmount(11),
            target=TargetAddress(app2.raiden.address),
            identifier=PaymentID(2),
            secret=Secret(b"2" * 32),
        )
        assert patched.call_count == 1

        # Mediator should not re-query PFS
        locked_transfer = factories.create(
            factories.LockedTransferProperties(
                amount=TokenAmount(5),
                initiator=factories.HOP1,
                target=TargetAddress(app2.raiden.address),
                sender=factories.HOP1,
                pkey=factories.HOP1_KEY,
                token=token_address,
                canonical_identifier=factories.make_canonical_identifier(
                    token_network_address=token_network_address
                ),
            )
        )
        app0.raiden.on_messages([locked_transfer])
        assert patched.call_count == 1
Beispiel #22
0
def test_mediator_task_view():
    """Same as above for mediator tasks."""
    secret1 = factories.make_secret(1)
    locked_amount1 = 11
    payee_transfer = factories.create(
        factories.LockedTransferProperties(secret=secret1))
    payer_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                secret=secret1,
                payment_identifier=1,
                balance_proof=factories.BalanceProofProperties(
                    locked_amount=locked_amount1, ),
            ), ))
    secrethash1 = payee_transfer.lock.secrethash
    initiator = payee_transfer.initiator
    initiator_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                address=initiator, balance=100), ))
    routes = [factories.route_from_channel(initiator_channel)]
    transfer_state1 = MediatorTransferState(secrethash=secrethash1,
                                            routes=routes)
    transfer_state1.transfers_pair.append(
        MediationPairState(
            payer_transfer=payer_transfer,
            payee_transfer=payee_transfer,
            payee_address=payee_transfer.target,
        ))
    task1 = MediatorTask(
        token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state1,
    )

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

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

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

    assert pending_transfer.get('role') == waiting_transfer.get(
        'role') == 'mediator'
    assert pending_transfer.get('payment_identifier') == '1'
    assert waiting_transfer.get('payment_identifier') == '2'
    assert pending_transfer.get('locked_amount') == str(locked_amount1)
    assert waiting_transfer.get('locked_amount') == str(locked_amount2)
Beispiel #23
0
def test_can_round_trip_serialize_locked_transfer():
    locked_transfer = factories.create(
        factories.LockedTransferProperties(sender=ADDRESS, pkey=PRIVKEY))

    as_dict = DictSerializer.serialize(locked_transfer)
    assert DictSerializer.deserialize(as_dict) == locked_transfer
def test_regression_mediator_task_no_routes():
    """ The mediator must only be cleared after the waiting transfer's lock has
    been handled.

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

    channels = make_channel_set([
        NettingChannelStateProperties(
            our_state=NettingChannelEndStateProperties(balance=0),
            partner_state=NettingChannelEndStateProperties(
                balance=10,
                address=HOP2,
                privatekey=HOP2_KEY,
            ),
        ),
    ])

    payer_transfer = factories.make_signed_transfer_for(
        channels[0],
        factories.LockedTransferSignedStateProperties(
            sender=HOP2,
            pkey=HOP2_KEY,
            transfer=factories.LockedTransferProperties(expiration=30),
        ))

    init_state_change = ActionInitMediator(
        channels.get_routes(),
        channels.get_route(0),
        payer_transfer,
    )
    init_iteration = mediator.state_transition(
        mediator_state=None,
        state_change=init_state_change,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=channels.nodeaddresses_to_networkstates,
        pseudo_random_generator=pseudo_random_generator,
        block_number=5,
        block_hash=factories.make_block_hash(),
    )

    msg = 'The task must not be cleared, even if there is no route to forward the transfer'
    assert init_iteration.new_state is not None, msg
    assert init_iteration.new_state.waiting_transfer.transfer == payer_transfer
    assert search_for_item(init_iteration.events, SendLockedTransfer,
                           {}) is None
    assert search_for_item(init_iteration.events, SendRefundTransfer,
                           {}) is None

    secrethash = UNIT_SECRETHASH
    lock = channels[0].partner_state.secrethashes_to_lockedlocks[secrethash]

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

    message_identifier = message_identifier_from_prng(pseudo_random_generator)

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

    receive_expired_iteration = mediator.state_transition(
        mediator_state=expire_block_iteration.new_state,
        state_change=ReceiveLockExpired(
            balance_proof=balance_proof,
            secrethash=secrethash,
            message_identifier=message_identifier,
        ),
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=channels.nodeaddresses_to_networkstates,
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
        block_hash=block_hash,
    )

    msg = 'The only used channel had the lock cleared, the task must be cleared'
    assert receive_expired_iteration.new_state is None, msg
    assert secrethash not in channels[
        0].partner_state.secrethashes_to_lockedlocks
Beispiel #25
0
from raiden.messages.synchronization import Delivered, Processed
from raiden.messages.transfers import RevealSecret, SecretRequest
from raiden.messages.withdraw import WithdrawConfirmation, WithdrawExpired, WithdrawRequest
from raiden.storage.serialization import JSONSerializer
from raiden.storage.serialization.serializer import MessageSerializer
from raiden.tests.utils import factories
from raiden.transfer import state, state_change
from raiden.utils.signer import LocalSigner

# Required for test_message_identical. It would be better to have a set of
# messages that don't depend on randomness for that test. But right now, we
# don't have that.
random.seed(1)

message_factories = (
    factories.LockedTransferProperties(),
    factories.RefundTransferProperties(),
    factories.LockExpiredProperties(),
    factories.UnlockProperties(),
)
messages = [factories.create(factory) for factory in message_factories]

# TODO Handle these with factories once #5091 is implemented
messages.append(
    Delivered(
        delivered_message_identifier=factories.make_message_identifier(),
        signature=factories.make_signature(),
    )
)
messages.append(
    Processed(