Example #1
0
def test_get_status():
    failed_status = TransactionExecutionStatus(
        finished_block_number=10, result=TransactionExecutionStatus.FAILURE)

    close_failed = factories.create(
        factories.NettingChannelStateProperties(
            close_transaction=failed_status))
    assert get_status(close_failed) == ChannelState.STATE_UNUSABLE

    settle_failed = factories.create(
        factories.NettingChannelStateProperties(
            settle_transaction=failed_status))
    assert get_status(settle_failed) == ChannelState.STATE_UNUSABLE
Example #2
0
def test_handle_block_closed_channel():
    channel_state = factories.create(
        factories.NettingChannelStateProperties(
            close_transaction=TransactionExecutionStatus(
                finished_block_number=50,
                result=TransactionExecutionStatus.SUCCESS),
            settle_timeout=50,
        ))
    pseudo_random_generator = random.Random()
    block = Block(block_number=90,
                  gas_limit=100000,
                  block_hash=factories.make_block_hash())
    before_settle = handle_block(
        channel_state=channel_state,
        state_change=block,
        block_number=block.block_number,
        pseudo_random_generator=pseudo_random_generator,
    )
    assert get_status(before_settle.new_state) == ChannelState.STATE_CLOSED
    assert not before_settle.events

    block = Block(block_number=102,
                  gas_limit=100000,
                  block_hash=factories.make_block_hash())
    after_settle = handle_block(
        channel_state=before_settle.new_state,
        state_change=block,
        block_number=block.block_number,
        pseudo_random_generator=pseudo_random_generator,
    )
    assert get_status(after_settle.new_state) == ChannelState.STATE_SETTLING
    assert after_settle.events
Example #3
0
def test_get_batch_unlock_gain():
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state = replace(
        channel_state.our_state,
        secrethashes_to_lockedlocks={
            factories.make_keccak_hash(): make_hash_time_lock_state(1),
            factories.make_keccak_hash(): make_hash_time_lock_state(2),
        },
        secrethashes_to_unlockedlocks={
            factories.make_keccak_hash(): make_unlock_partial_proof_state(4)
        },
        secrethashes_to_onchain_unlockedlocks={
            factories.make_keccak_hash(): make_unlock_partial_proof_state(8)
        },
    )
    channel_state.partner_state = replace(
        channel_state.partner_state,
        secrethashes_to_lockedlocks={
            factories.make_keccak_hash(): make_hash_time_lock_state(16)
        },
        secrethashes_to_unlockedlocks={
            factories.make_keccak_hash(): make_unlock_partial_proof_state(32)
        },
        secrethashes_to_onchain_unlockedlocks={
            factories.make_keccak_hash(): make_unlock_partial_proof_state(64),
            factories.make_keccak_hash(): make_unlock_partial_proof_state(128),
        },
    )
    unlock_gain = get_batch_unlock_gain(channel_state)
    assert unlock_gain.from_partner_locks == 192
    assert unlock_gain.from_our_locks == 7
Example #4
0
def make_from_route_from_counter(counter):
    from_channel = factories.create(
        factories.NettingChannelStateProperties(
            canonical_identifier=factories.make_canonical_identifier(),
            token_address=factories.make_token_address(),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=next(counter), address=factories.HOP1),
        ))
    from_hop = factories.make_hop_from_channel(from_channel)

    expiration = BlockExpiration(factories.UNIT_REVEAL_TIMEOUT + 1)

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        factories.LockedTransferSignedStateProperties(
            transferred_amount=TokenAmount(0),
            canonical_identifier=factories.make_canonical_identifier(
                token_network_address=from_channel.token_network_address),
            amount=TokenAmount(1),
            expiration=expiration,
            secret=sha3(factories.make_secret(next(counter))),
            initiator=factories.make_initiator_address(),
            target=factories.make_target_address(),
            payment_identifier=next(counter),
            sender=factories.HOP1,
            pkey=factories.HOP1_KEY,
        ),
    )
    return from_hop, from_transfer
Example #5
0
def test_target_task_view():
    """Same as above for target tasks."""
    secret = factories.make_secret()
    transfer = factories.create(
        factories.LockedTransferSignedStateProperties(secret=secret))
    secrethash = transfer.lock.secrethash
    mediator = factories.make_address()
    mediator_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                address=mediator, balance=TokenAmount(100))))
    transfer_state = TargetTransferState(
        from_hop=HopState(
            channel_identifier=mediator_channel.canonical_identifier.
            channel_identifier,
            node_address=mediator,
        ),
        transfer=transfer,
        secret=secret,
    )
    task = TargetTask(
        canonical_identifier=mediator_channel.canonical_identifier,
        target_state=transfer_state)
    payment_mapping = {secrethash: cast(TransferTask, task)}

    view = transfer_tasks_view(payment_mapping)

    assert len(view) == 1
    pending_transfer = view[0]
    assert pending_transfer.get("role") == "target"
    # pylint: disable=no-member
    assert pending_transfer.get("locked_amount") == str(
        transfer.balance_proof.locked_amount)
    assert pending_transfer.get("payment_identifier") == str(
        transfer.payment_identifier)
Example #6
0
def netting_channel_state(chain_state, token_network_state,
                          token_network_registry_state, partner):
    if partner is None:
        partner = factories.make_address()
    canonical_identifier = factories.make_canonical_identifier(
        token_network_address=token_network_state.address)
    channel_state = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=TokenAmount(10), address=chain_state.our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=TokenAmount(10), address=partner),
            token_address=token_network_state.token_address,
            token_network_registry_address=token_network_registry_state.
            address,
            canonical_identifier=canonical_identifier,
        ))

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

    return channel_state
Example #7
0
def test_fee_update():
    channel_state = factories.create(factories.NettingChannelStateProperties())
    message = PFSFeeUpdate.from_channel_state(channel_state)
    message.sign(signer)

    assert message == DictSerializer.deserialize(
        DictSerializer.serialize(message))
Example #8
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.LockedTransferUnsignedStateProperties(secret=secret1))
    payer_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=secret1, payment_identifier=1,
            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.make_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(
            secret=secret2, payment_identifier=2,
            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)
Example #9
0
def test_target_task_view():
    """Same as above for target tasks."""
    secret = factories.make_secret()
    transfer = factories.create(
        factories.LockedTransferSignedStateProperties(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(
        canonical_identifier=mediator_channel.canonical_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)
Example #10
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)
Example #11
0
def test_events_for_onchain_secretreveal_with_unfit_channels():
    settle = factories.TransactionExecutionStatusProperties()
    settled = factories.create(
        factories.NettingChannelStateProperties(settle_transaction=settle))
    secret = factories.UNIT_SECRET
    block_hash = factories.make_block_hash()

    events = events_for_onchain_secretreveal(settled, secret, 10, block_hash)
    assert not events, "Secret reveal event should not be generated for settled channel"

    settle = factories.replace(settle,
                               result=TransactionExecutionStatus.FAILURE)
    unusable = factories.create(
        factories.NettingChannelStateProperties(settle_transaction=settle))

    events = events_for_onchain_secretreveal(unusable, secret, 10, block_hash)
    assert not events, "Secret reveal event should not be generated for unusable channel."
Example #12
0
def test_pfs_global_messages(
    local_matrix_servers,
    private_rooms,
    retry_interval,
    retries_before_backoff,
    monkeypatch,
    global_rooms,
):
    """
    Test that RaidenService sends UpdatePFS messages to global
    PATH_FINDING_BROADCASTING_ROOM room on newly received balance proofs.
    """
    transport = MatrixTransport({
        "global_rooms": global_rooms,  # FIXME: #3735
        "retries_before_backoff": retries_before_backoff,
        "retry_interval": retry_interval,
        "server": local_matrix_servers[0],
        "server_name": local_matrix_servers[0].netloc,
        "available_servers": [local_matrix_servers[0]],
        "private_rooms": private_rooms,
    })
    transport._client.api.retry_timeout = 0
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)
    raiden_service.config = dict(services=dict(monitoring_enabled=True))

    transport.start(raiden_service, raiden_service.message_handler, None)

    pfs_room_name = make_room_alias(transport.network_id,
                                    PATH_FINDING_BROADCASTING_ROOM)
    pfs_room = transport._global_rooms.get(pfs_room_name)
    assert isinstance(pfs_room, Room)
    pfs_room.send_text = MagicMock(spec=pfs_room.send_text)

    raiden_service.transport = transport
    transport.log = MagicMock()

    balance_proof = factories.create(HOP1_BALANCE_PROOF)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    monkeypatch.setattr(
        raiden.transfer.views,
        "get_channelstate_by_canonical_identifier",
        lambda *a, **kw: channel_state,
    )
    update_path_finding_service_from_balance_proof(
        raiden=raiden_service,
        chain_state=None,
        new_balance_proof=balance_proof)
    gevent.idle()

    with gevent.Timeout(2):
        while pfs_room.send_text.call_count < 1:
            gevent.idle()
    assert pfs_room.send_text.call_count == 1
    transport.stop()
    transport.get()
Example #13
0
def test_set_settled():
    channel = factories.create(
        factories.NettingChannelStateProperties(
            settle_transaction=TransactionExecutionStatus(
                finished_block_number=None, result=None)))

    assert get_status(channel) == ChannelState.STATE_SETTLING
    set_settled(channel, block_number=100)
    assert get_status(channel) == ChannelState.STATE_SETTLED
Example #14
0
def channel_properties(our_address, token_network_state):
    partner_privkey, address = factories.make_privkey_address()
    properties = factories.NettingChannelStateProperties(
        our_state=factories.NettingChannelEndStateProperties(balance=80, address=our_address),
        partner_state=factories.NettingChannelEndStateProperties(balance=80, address=address),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address
        ),
    )
    return properties, partner_privkey
Example #15
0
def test_get_state_change_with_transfer_by_secrethash():
    serializer = JSONSerializer()
    storage = SerializedSQLiteStorage(":memory:", serializer)

    mediator_secret, mediator_secrethash = factories.make_secret_with_hash()
    channels = factories.mediator_make_channel_pair()
    mediator_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=mediator_secret,
            target=channels.partner_address(1),
            initiator=channels.partner_address(0),
        )
    )
    mediator_state_change = factories.mediator_make_init_action(channels, mediator_transfer)

    target_secret, target_secrethash = factories.make_secret_with_hash()
    from_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                balance=100, address=factories.make_address()
            )
        )
    )
    target_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=target_secret,
            target=channels.our_address(0),
            initiator=channels.partner_address(1),
        )
    )

    target_state_change = ActionInitTarget(
        from_hop=HopState(
            node_address=from_channel.partner_state.address,
            channel_identifier=from_channel.canonical_identifier.channel_identifier,
        ),
        transfer=target_transfer,
        balance_proof=target_transfer.balance_proof,
        sender=target_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    assert storage.count_state_changes() == 0
    storage.write_state_changes([mediator_state_change, target_state_change])
    assert storage.count_state_changes() == 2

    restored = get_state_change_with_transfer_by_secrethash(storage, mediator_secrethash)
    assert isinstance(restored.data, ActionInitMediator)
    assert restored.data.from_transfer == mediator_transfer

    restored = get_state_change_with_transfer_by_secrethash(storage, target_secrethash)
    assert isinstance(restored.data, ActionInitTarget)
    assert restored.data.transfer == target_transfer
Example #16
0
def test_get_capacity():
    our_state = factories.create(
        factories.NettingChannelEndStateProperties(balance=TokenAmount(100)))
    channel_state = factories.create(
        factories.NettingChannelStateProperties(
            our_state=our_state,
            partner_state=factories.NettingChannelEndStateProperties(
                balance=TokenAmount(50)),
        ))
    assert channel.get_capacity(channel_state) == 150

    channel_state.our_state = replace(our_state, onchain_total_withdraw=50)
    assert channel.get_capacity(channel_state) == 100
Example #17
0
def test_update_pfs():
    properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY)
    balance_proof = factories.create(properties)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    message = UpdatePFS.from_channel_state(channel_state=channel_state)

    assert message.signature == b""
    privkey2, address2 = factories.make_privkey_address()
    signer2 = LocalSigner(privkey2)
    message.sign(signer2)
    assert recover(message._data_to_sign(), message.signature) == address2

    assert message == UpdatePFS.from_dict(message.to_dict())
Example #18
0
def test_update_pfs():
    properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY)
    balance_proof = factories.create(properties)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    message = PFSCapacityUpdate.from_channel_state(channel_state=channel_state)

    assert message.signature == EMPTY_SIGNATURE
    privkey2, address2 = factories.make_privkey_address()
    signer2 = LocalSigner(privkey2)
    message.sign(signer2)
    assert recover(message._data_to_sign(), message.signature) == address2

    assert message == DictSerializer.deserialize(DictSerializer.serialize(message))
Example #19
0
def test_update_fee_schedule_after_balance_change():
    channel_state = factories.create(
        factories.NettingChannelStateProperties(
            our_state=NettingChannelEndStateProperties(balance=100),
            partner_state=NettingChannelEndStateProperties(balance=0),
        )
    )

    fee_config = prepare_mediation_fee_config(
        cli_token_to_flat_fee=(),
        cli_token_to_proportional_fee=(),
        cli_token_to_proportional_imbalance_fee=((channel_state.token_address, 50_000),),  # 5%
        cli_cap_mediation_fees=True,
    )
    update_fee_schedule_after_balance_change(channel_state, fee_config)
    assert channel_state.fee_schedule.imbalance_penalty[0] == (0, 5)
    def new_channel(self):
        """Create a new partner address with private key and channel. The
        private key and channels are listed in the instance's dictionaries,
        the address is returned and should be added to the partners Bundle.
        """

        partner_privkey, partner_address = factories.make_privkey_address()

        self.address_to_privkey[partner_address] = partner_privkey
        self.address_to_channel[partner_address] = factories.create(
            factories.NettingChannelStateProperties(
                our_state=factories.NettingChannelEndStateProperties(
                    balance=1000, address=self.address),
                partner_state=factories.NettingChannelEndStateProperties(
                    balance=1000, address=partner_address),
                canonical_identifier=factories.make_canonical_identifier(
                    token_network_address=self.token_network_address),
            ))

        return partner_address
Example #21
0
def test_update_channel_reveal_timeout():
    pseudo_random_generator = random.Random()
    channel_state = factories.create(
        factories.NettingChannelStateProperties(settle_timeout=500,
                                                reveal_timeout=50))

    invalid_reveal_timeout = 260
    valid_reveal_timeout = 250

    set_reveal_timeout = ActionChannelSetRevealTimeout(
        canonical_identifier=channel_state.canonical_identifier,
        reveal_timeout=invalid_reveal_timeout,
    )

    iteration = channel.state_transition(
        channel_state=channel_state,
        state_change=set_reveal_timeout,
        block_number=1,
        block_hash=make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    assert iteration.new_state == channel_state
    assert isinstance(iteration.events[0], EventInvalidActionSetRevealTimeout)

    set_reveal_timeout = ActionChannelSetRevealTimeout(
        canonical_identifier=channel_state.canonical_identifier,
        reveal_timeout=250)

    iteration = channel.state_transition(
        channel_state=channel_state,
        state_change=set_reveal_timeout,
        block_number=1,
        block_hash=make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    assert iteration.new_state.reveal_timeout == valid_reveal_timeout
def test_pfs_broadcast_messages(
    local_matrix_servers,
    retry_interval_initial,
    retry_interval_max,
    retries_before_backoff,
    monkeypatch,
    broadcast_rooms,
    route_mode,
):
    """
    Test that RaidenService broadcasts PFSCapacityUpdate messages to
    PATH_FINDING_BROADCASTING_ROOM room on newly received balance proofs.
    """
    transport = MatrixTransport(
        config=MatrixTransportConfig(
            broadcast_rooms=broadcast_rooms,
            retries_before_backoff=retries_before_backoff,
            retry_interval_initial=retry_interval_initial,
            retry_interval_max=retry_interval_max,
            server=local_matrix_servers[0],
            available_servers=[local_matrix_servers[0]],
        ),
        environment=Environment.DEVELOPMENT,
    )
    transport._client.api.retry_timeout = 0
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)
    raiden_service.config.services.monitoring_enabled = True
    raiden_service.routing_mode = route_mode

    transport.start(raiden_service, [], None)

    pfs_room_name = make_room_alias(transport.chain_id, PATH_FINDING_BROADCASTING_ROOM)
    pfs_room = transport._broadcast_rooms.get(pfs_room_name)
    assert isinstance(pfs_room, Room)
    pfs_room.send_text = MagicMock(spec=pfs_room.send_text)

    raiden_service.transport = transport
    transport.log = MagicMock()

    # send PFSCapacityUpdate
    balance_proof = factories.create(HOP1_BALANCE_PROOF)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    monkeypatch.setattr(
        raiden.transfer.views,
        "get_channelstate_by_canonical_identifier",
        lambda *a, **kw: channel_state,
    )
    send_pfs_update(raiden=raiden_service, canonical_identifier=balance_proof.canonical_identifier)
    gevent.idle()
    with gevent.Timeout(2):
        while pfs_room.send_text.call_count < 1:
            gevent.idle()
    assert pfs_room.send_text.call_count == 1

    # send PFSFeeUpdate
    channel_state = factories.create(factories.NettingChannelStateProperties())
    fee_update = PFSFeeUpdate.from_channel_state(channel_state)
    fee_update.sign(raiden_service.signer)
    raiden_service.transport.broadcast(PATH_FINDING_BROADCASTING_ROOM, fee_update)
    with gevent.Timeout(2):
        while pfs_room.send_text.call_count < 2:
            gevent.idle()
    assert pfs_room.send_text.call_count == 2
    msg_data = json.loads(pfs_room.send_text.call_args[0][0])
    assert msg_data["type"] == "PFSFeeUpdate"

    transport.stop()
    transport.greenlet.get()
def test_monitoring_broadcast_messages(
    local_matrix_servers,
    retry_interval_initial,
    retry_interval_max,
    retries_before_backoff,
    monkeypatch,
    broadcast_rooms,
):
    """
    Test that RaidenService broadcast RequestMonitoring messages to
    MONITORING_BROADCASTING_ROOM room on newly received balance proofs.
    """
    transport = MatrixTransport(
        config=MatrixTransportConfig(
            broadcast_rooms=broadcast_rooms + [MONITORING_BROADCASTING_ROOM],
            retries_before_backoff=retries_before_backoff,
            retry_interval_initial=retry_interval_initial,
            retry_interval_max=retry_interval_max,
            server=local_matrix_servers[0],
            available_servers=[local_matrix_servers[0]],
        ),
        environment=Environment.DEVELOPMENT,
    )
    transport._client.api.retry_timeout = 0
    transport._send_raw = MagicMock()
    raiden_service = MockRaidenService(None)
    raiden_service.config = RaidenConfig(
        chain_id=1234,
        environment_type=Environment.DEVELOPMENT,
        services=ServiceConfig(monitoring_enabled=True),
    )

    transport.start(raiden_service, [], None)

    ms_room_name = make_room_alias(transport.chain_id, MONITORING_BROADCASTING_ROOM)
    ms_room = transport._broadcast_rooms.get(ms_room_name)
    assert isinstance(ms_room, Room)
    ms_room.send_text = MagicMock(spec=ms_room.send_text)

    raiden_service.transport = transport
    transport.log = MagicMock()

    balance_proof = factories.create(HOP1_BALANCE_PROOF)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    monkeypatch.setattr(
        raiden.transfer.views,
        "get_channelstate_by_canonical_identifier",
        lambda *a, **kw: channel_state,
    )
    monkeypatch.setattr(raiden.transfer.channel, "get_balance", lambda *a, **kw: 123)
    raiden_service.user_deposit.effective_balance.return_value = MONITORING_REWARD

    update_monitoring_service_from_balance_proof(
        raiden=raiden_service,
        chain_state=None,
        new_balance_proof=balance_proof,
        non_closing_participant=HOP1,
    )
    gevent.idle()

    with gevent.Timeout(2):
        while ms_room.send_text.call_count < 1:
            gevent.idle()
    assert ms_room.send_text.call_count == 1

    transport.stop()
    transport.greenlet.get()
Example #24
0
def test_mediator_task_view():
    """Same as above for mediator tasks."""
    secret1 = factories.make_secret(1)
    locked_amount1 = TokenAmount(11)
    payee_transfer = factories.create(
        factories.LockedTransferUnsignedStateProperties(secret=secret1))
    payer_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=secret1,
            payment_identifier=PaymentID(1),
            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=TokenAmount(100))))
    route_state = RouteState(
        route=[payee_transfer.target],
        forward_channel_id=initiator_channel.canonical_identifier.
        channel_identifier,
    )

    transfer_state1 = MediatorTransferState(secrethash=secrethash1,
                                            routes=[route_state])
    # pylint: disable=E1101
    transfer_state1.transfers_pair.append(
        MediationPairState(
            payer_transfer=payer_transfer,
            payee_transfer=payee_transfer,
            payee_address=payee_transfer.target,
        ))
    task1 = MediatorTask(
        token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state1)

    secret2 = factories.make_secret(2)
    locked_amount2 = TokenAmount(13)
    transfer2 = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=secret2,
            payment_identifier=PaymentID(2),
            locked_amount=locked_amount2))
    secrethash2 = transfer2.lock.secrethash
    transfer_state2 = MediatorTransferState(secrethash=secrethash2,
                                            routes=[route_state])
    transfer_state2.waiting_transfer = WaitingTransferState(transfer=transfer2)
    task2 = MediatorTask(
        token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS,
        mediator_state=transfer_state2)

    payment_mapping = {
        secrethash1: cast(TransferTask, task1),
        secrethash2: cast(TransferTask, 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)
Example #25
0
def test_events_for_onchain_secretreveal_typechecks_secret():
    channel = factories.create(factories.NettingChannelStateProperties())
    block_hash = factories.make_block_hash()
    with pytest.raises(ValueError):
        events_for_onchain_secretreveal(channel, "This is an invalid secret",
                                        10, block_hash)
def test_routing_priority(chain_state, token_network_state, one_to_n_address,
                          our_address):
    open_block_number = factories.make_block_number()
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()
    address4 = factories.make_address()
    pseudo_random_generator = random.Random()
    # Create a network with the following topology
    #
    # our  ----- 1/1 ----> (1)
    #  |                    |
    #  |                    |
    #  2/0                  x
    #  |                    |
    #  v                    v
    # (2)  ----- x ----->  (3)
    #  |                    |
    #  |                    |
    #  x                    x
    #  |                    |
    #  v                    v
    # (4)                  (4)

    channel_state1 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=1, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=1, address=address1),
        ))
    channel_state2 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=2, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address2),
        ))

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration1 = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_iteration2 = token_network.state_transition(
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=3),
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration3 = token_network.state_transition(
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration4 = token_network.state_transition(
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration5 = token_network.state_transition(
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_state_change6 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address2,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    token_network.state_transition(
        token_network_state=channel_new_iteration5.new_state,
        state_change=channel_new_state_change6,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    # test routing priority with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
    }

    error_msg, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes, error_msg
    assert routes[0].next_hop_address == address1, error_msg
    assert routes[1].next_hop_address == address2, error_msg

    # number of hops overwrites refunding capacity (route over node 2 involves less hops)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes[0].next_hop_address == address2
    assert routes[1].next_hop_address == address1
def test_routing_issue2663(chain_state, token_network_state, one_to_n_address,
                           our_address):
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    address3 = factories.make_address()
    address4 = factories.make_address()
    pseudo_random_generator = random.Random()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1) <------50------
    #  |                                    |
    #  |                                    |
    # 100                                  (4)
    #  |                                    ^
    #  v                                    |
    # (2)  ----- 100 --->  (3) <-------100---

    channel_state1 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=50, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address1),
        ))
    channel_state2 = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=100, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address2),
        ))

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration1 = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    channel_new_iteration2 = token_network.state_transition(
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=3),
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    channel_new_iteration3 = token_network.state_transition(
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_iteration4 = token_network.state_transition(
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=5),
        participant1=address1,
        participant2=address4,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )
    channel_new_iteration5 = token_network.state_transition(
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = channel_new_iteration5.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 5
    assert len(graph_state.network.edges()) == 5

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    error_msg, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes1, error_msg
    assert routes1[0].next_hop_address == address1, error_msg
    assert routes1[1].next_hop_address == address2, error_msg

    # test routing with node 2 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.UNREACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes1[0].next_hop_address == address1

    # test routing with node 3 offline
    # the routing doesn't care as node 3 is not directly connected
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.UNREACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address4,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    assert routes1[0].next_hop_address == address1
    assert routes1[1].next_hop_address == address2

    # test routing with node 1 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.UNREACHABLE,
        address2: NetworkState.REACHABLE,
        address3: NetworkState.REACHABLE,
        address4: NetworkState.REACHABLE,
    }

    _, routes1, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address3,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].next_hop_address == address2
def test_multiple_channel_states(chain_state, token_network_state,
                                 channel_properties):
    open_block_number = 10
    open_block_hash = factories.make_block_hash()

    pseudo_random_generator = random.Random()

    properties, pkey = channel_properties
    channel_state = factories.create(properties)

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

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

    lock_amount = 30
    lock_expiration = 20
    lock_secret = keccak(b"test_end_state")
    lock_secrethash = sha256(lock_secret).digest()
    lock = HashTimeLockState(lock_amount, lock_expiration, lock_secrethash)

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

    from_hop = factories.make_hop_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_hop=from_hop,
        transfer=mediated_transfer,
        balance_proof=mediated_transfer.balance_proof,
        sender=mediated_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    node.state_transition(chain_state, init_target)

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

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

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

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

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

    # Create new channel while the previous one is pending unlock
    new_channel_properties = factories.create_properties(
        factories.NettingChannelStateProperties(
            canonical_identifier=factories.make_canonical_identifier()),
        defaults=properties,
    )
    new_channel_state = factories.create(new_channel_properties)

    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=new_channel_state,
        block_number=closed_block_number + 1,
        block_hash=factories.make_block_hash(),
    )

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

    token_network_state_after_new_open = channel_new_iteration.new_state
    ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels

    assert len(ids_to_channels) == 2
    assert channel_state.identifier in ids_to_channels
def test_internal_routing_mediation_fees(chain_state, token_network_state,
                                         one_to_n_address, our_address):
    """
    Checks that requesting a route for a single-hop transfer
    will return the route with estimated_fee of zero.
    """
    open_block_number = 10
    open_block_number_hash = factories.make_block_hash()
    address1 = factories.make_address()
    address2 = factories.make_address()
    pseudo_random_generator = random.Random()

    direct_channel_state = factories.create(
        factories.NettingChannelStateProperties(
            our_state=factories.NettingChannelEndStateProperties(
                balance=50, address=our_address),
            partner_state=factories.NettingChannelEndStateProperties(
                balance=0, address=address1),
        ))

    # create new channels as participant
    direct_channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=direct_channel_state,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    direct_channel_new_iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=direct_channel_new_state_change,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    route_new_state_change = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address,
            channel_identifier=4),
        participant1=address1,
        participant2=address2,
        block_number=open_block_number,
        block_hash=open_block_number_hash,
    )

    route_new_iteration = token_network.state_transition(
        token_network_state=direct_channel_new_iteration.new_state,
        state_change=route_new_state_change,
        block_number=open_block_number + 10,
        block_hash=factories.make_block_hash(),
        pseudo_random_generator=pseudo_random_generator,
    )

    graph_state = route_new_iteration.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NetworkState.REACHABLE,
        address2: NetworkState.REACHABLE,
    }

    # Routing to our direct partner would require 0 mediation fees.x
    _, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes[0].estimated_fee == 0

    # Routing to our address2 through address1 would charge 2%
    error_msg, routes, _ = get_best_routes(
        chain_state=chain_state,
        token_network_address=token_network_state.address,
        one_to_n_address=one_to_n_address,
        from_address=our_address,
        to_address=address2,
        amount=50,
        previous_address=None,
        pfs_config=None,
        privkey=b"",  # not used if pfs is not configured
    )
    assert routes, error_msg
    assert routes[0].estimated_fee == round(INTERNAL_ROUTING_DEFAULT_FEE_PERC *
                                            50), error_msg
Example #30
0
def test_mediator_skips_used_routes():
    prng = random.Random()
    block_number = 3
    defaults = factories.NettingChannelStateProperties(
        our_state=factories.NettingChannelEndStateProperties.OUR_STATE,
        partner_state=factories.NettingChannelEndStateProperties(
            balance=UNIT_TRANSFER_AMOUNT),
        open_transaction=factories.TransactionExecutionStatusProperties(
            started_block_number=1, finished_block_number=2, result="success"),
    )
    properties = [
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP1_KEY, address=factories.HOP1)),
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP2_KEY, address=factories.HOP2)),
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                privatekey=factories.HOP3_KEY, address=factories.HOP3)),
    ]
    channels = factories.make_channel_set(properties=properties,
                                          number_of_channels=3,
                                          defaults=defaults)
    bob = channels.channels[1].partner_state.address
    charlie = channels.channels[2].partner_state.address
    dave = factories.make_address()
    eric = factories.make_address()
    locked_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=10,
            routes=[
                [
                    factories.UNIT_OUR_ADDRESS, bob, dave,
                    factories.UNIT_TRANSFER_TARGET
                ],
                [
                    factories.UNIT_OUR_ADDRESS, bob, eric,
                    factories.UNIT_TRANSFER_TARGET
                ],
                [
                    factories.UNIT_OUR_ADDRESS, charlie, eric,
                    factories.UNIT_TRANSFER_TARGET
                ],
            ],
            canonical_identifier=channels.channels[0].canonical_identifier,
            pkey=factories.HOP1_KEY,
            sender=factories.HOP1,
        ))
    init_action = factories.mediator_make_init_action(channels=channels,
                                                      transfer=locked_transfer)
    nodeaddresses_to_networkstates = {
        channel.partner_state.address: NetworkState.REACHABLE
        for channel in channels.channels
    }

    transition_result = mediator.handle_init(
        state_change=init_action,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )
    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events

    assert len(mediator_state.routes) == 3
    assert mediator_state.routes[0].route[1] == bob
    assert mediator_state.routes[1].route[1] == bob
    assert mediator_state.routes[2].route[1] == charlie
    # now we receive a refund from whoever we forwarded to (should be HOP2)
    assert isinstance(events[-1], SendLockedTransfer)
    assert events[-1].recipient == factories.HOP2

    last_pair = mediator_state.transfers_pair[-1]
    canonical_identifier = last_pair.payee_transfer.balance_proof.canonical_identifier
    lock_expiration = last_pair.payee_transfer.lock.expiration
    payment_identifier = last_pair.payee_transfer.payment_identifier

    received_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=lock_expiration,
            payment_identifier=payment_identifier,
            canonical_identifier=canonical_identifier,
            sender=factories.HOP2,
            pkey=factories.HOP2_KEY,
            message_identifier=factories.make_message_identifier(),
        ))

    refund_state_change = ReceiveTransferRefund(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
    )
    transition_result = mediator.handle_refundtransfer(
        mediator_state=mediator_state,
        mediator_state_change=refund_state_change,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )

    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events
    assert mediator_state.transfers_pair[-1].payee_address == charlie

    # now we should have a forward transfer to HOP3
    assert isinstance(events[-1], SendLockedTransfer)
    assert events[-1].recipient == factories.HOP3

    # now we will receive a refund from HOP3

    last_pair = mediator_state.transfers_pair[-1]
    canonical_identifier = last_pair.payee_transfer.balance_proof.canonical_identifier
    lock_expiration = last_pair.payee_transfer.lock.expiration
    payment_identifier = last_pair.payee_transfer.payment_identifier

    received_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            expiration=lock_expiration,
            payment_identifier=payment_identifier,
            canonical_identifier=canonical_identifier,
            sender=factories.HOP3,
            pkey=factories.HOP3_KEY,
            message_identifier=factories.make_message_identifier(),
        ))

    refund_state_change = ReceiveTransferRefund(
        transfer=received_transfer,
        balance_proof=received_transfer.balance_proof,
        sender=received_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    transition_result = mediator.handle_refundtransfer(
        mediator_state=mediator_state,
        mediator_state_change=refund_state_change,
        channelidentifiers_to_channels=channels.channel_map,
        nodeaddresses_to_networkstates=nodeaddresses_to_networkstates,
        pseudo_random_generator=prng,
        block_number=block_number,
    )

    mediator_state = transition_result.new_state
    events = transition_result.events
    assert mediator_state is not None
    assert events

    # no other routes available, so refund HOP1
    assert isinstance(events[-1], SendRefundTransfer)
    assert events[-1].recipient == factories.HOP1