Exemple #1
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)
def test_invalid_instantiation_action_init_mediator_and_target(additional_args):
    hop_state = HopState(
        node_address=factories.make_address(),
        channel_identifier=factories.make_channel_identifier(),
    )

    route_state = RouteState(
        route=[factories.make_address()], forward_channel_id=factories.make_channel_identifier()
    )

    not_a_route_state = object()
    valid_transfer = factories.create(factories.LockedTransferSignedStateProperties())
    wrong_type_transfer = factories.create(factories.TransferDescriptionProperties())

    with pytest.raises(ValueError):
        ActionInitMediator(
            from_transfer=wrong_type_transfer,
            from_hop=hop_state,
            route_states=[route_state],
            **additional_args,
        )

    with pytest.raises(ValueError):
        ActionInitMediator(
            from_transfer=valid_transfer,
            from_hop=not_a_route_state,
            route_states=[route_state],
            **additional_args,
        )

    with pytest.raises(ValueError):
        ActionInitTarget(transfer=wrong_type_transfer, from_hop=hop_state, **additional_args)

    with pytest.raises(ValueError):
        ActionInitTarget(transfer=valid_transfer, from_hop=not_a_route_state, **additional_args)
Exemple #3
0
def test_subdispatch_to_paymenttask_target(chain_state, netting_channel_state):
    target_state = TargetTransferState(
        from_hop=HopState(
            node_address=netting_channel_state.partner_state.address,
            channel_identifier=netting_channel_state.canonical_identifier.
            channel_identifier,
        ),
        transfer=factories.create(
            factories.LockedTransferSignedStateProperties()),
        secret=UNIT_SECRET,
    )
    subtask = TargetTask(
        canonical_identifier=netting_channel_state.canonical_identifier,
        target_state=target_state)
    chain_state.payment_mapping.secrethashes_to_task[UNIT_SECRETHASH] = subtask

    lock = factories.HashTimeLockState(amount=0,
                                       expiration=2,
                                       secrethash=UNIT_SECRETHASH)

    netting_channel_state.partner_state.secrethashes_to_lockedlocks[
        UNIT_SECRETHASH] = lock
    netting_channel_state.partner_state.pending_locks = PendingLocksState(
        [bytes(lock.encoded)])
    state_change = Block(
        block_number=chain_state.block_number,
        gas_limit=GAS_LIMIT,
        block_hash=chain_state.block_hash,
    )
    transition_result = subdispatch_to_paymenttask(chain_state=chain_state,
                                                   state_change=state_change,
                                                   secrethash=UNIT_SECRETHASH)
    assert transition_result.events == []
    assert transition_result.new_state == chain_state

    chain_state.block_number = 20

    balance_proof: BalanceProofSignedState = factories.create(
        factories.BalanceProofSignedStateProperties(
            canonical_identifier=netting_channel_state.canonical_identifier,
            sender=netting_channel_state.partner_state.address,
            transferred_amount=0,
            pkey=factories.UNIT_TRANSFER_PKEY,
            locksroot=LOCKSROOT_OF_NO_LOCKS,
        ))
    state_change = ReceiveLockExpired(
        balance_proof=balance_proof,
        sender=netting_channel_state.partner_state.address,
        secrethash=UNIT_SECRETHASH,
        message_identifier=factories.make_message_identifier(),
    )
    transition_result = subdispatch_to_paymenttask(chain_state=chain_state,
                                                   state_change=state_change,
                                                   secrethash=UNIT_SECRETHASH)
    msg = "ReceiveLockExpired should have cleared the task"
    assert UNIT_SECRETHASH not in chain_state.payment_mapping.secrethashes_to_task, msg
    assert len(
        transition_result.events), "ReceiveLockExpired should generate events"
    assert transition_result.new_state == chain_state
Exemple #4
0
    def handle_message_lockedtransfer(
        raiden: "RaidenService", message: LockedTransfer  # pylint: disable=unused-argument
    ) -> List[StateChange]:
        secrethash = message.lock.secrethash
        # We must check if the secret was registered against the latest block,
        # even if the block is forked away and the transaction that registers
        # the secret is removed from the blockchain. The rationale here is that
        # someone else does know the secret, regardless of the chain state, so
        # the node must not use it to start a payment.
        #
        # For this particular case, it's preferable to use `latest` instead of
        # having a specific block_hash, because it's preferable to know if the secret
        # was ever known, rather than having a consistent view of the blockchain.
        registered = raiden.default_secret_registry.is_secret_registered(
            secrethash=secrethash, block_identifier=BLOCK_ID_LATEST
        )
        if registered:
            log.warning(
                f"Ignoring received locked transfer with secrethash {to_hex(secrethash)} "
                f"since it is already registered in the secret registry"
            )
            return []

        assert message.sender, "Invalid message dispatched, it should be signed"

        from_transfer = lockedtransfersigned_from_message(message)
        from_hop = HopState(
            node_address=message.sender,
            # pylint: disable=E1101
            channel_identifier=from_transfer.balance_proof.channel_identifier,
        )
        if message.target == TargetAddress(raiden.address):
            raiden.immediate_health_check_for(Address(message.initiator))
            return [
                ActionInitTarget(
                    from_hop=from_hop,
                    transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,
                )
            ]
        else:
            route_states = routing.resolve_routes(
                routes=message.metadata.routes,
                token_network_address=from_transfer.balance_proof.token_network_address,
                chain_state=views.state_from_raiden(raiden),
            )
            return [
                ActionInitMediator(
                    from_hop=from_hop,
                    route_states=route_states,
                    from_transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,
                )
            ]
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
Exemple #6
0
def locked_transfer_to_action_init_target(
        locked_transfer: LockedTransfer) -> ActionInitTarget:
    from_transfer = lockedtransfersigned_from_message(locked_transfer)
    channel_id = from_transfer.balance_proof.channel_identifier  # pylint: disable=no-member
    from_hop = HopState(node_address=Address(locked_transfer.initiator),
                        channel_identifier=channel_id)
    init_target_statechange = ActionInitTarget(
        from_hop=from_hop,
        transfer=from_transfer,
        balance_proof=from_transfer.balance_proof,
        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    return init_target_statechange
Exemple #7
0
def action_init_initiator_to_action_init_target(
    action: ActionInitInitiator,
    channel: NettingChannelState,
    block_number: BlockNumber,
    route_state: RouteState,
    address: Address,
    private_key: PrivateKey,
) -> ActionInitTarget:
    transfer = signed_transfer_from_description(
        private_key=private_key,
        description=action.transfer,
        channel=channel,
        message_id=factories.make_message_identifier(),
        block_number=block_number,
        route_state=route_state,
        route_states=action.routes,
    )
    from_hop = HopState(node_address=address,
                        channel_identifier=channel.identifier)
    return ActionInitTarget(from_hop=from_hop,
                            transfer=transfer,
                            sender=address,
                            balance_proof=transfer.balance_proof)