Esempio n. 1
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,
                )
            ]
Esempio n. 2
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
Esempio n. 3
0
    def handle_message_refundtransfer(
        raiden: "RaidenService", message: RefundTransfer
    ) -> List[StateChange]:
        chain_state = views.state_from_raiden(raiden)
        from_transfer = lockedtransfersigned_from_message(message=message)

        role = views.get_transfer_role(
            chain_state=chain_state, secrethash=from_transfer.lock.secrethash
        )

        state_changes: List[StateChange] = []

        if role == "initiator":
            old_secret = views.get_transfer_secret(chain_state, from_transfer.lock.secrethash)
            is_secret_known = old_secret is not None and old_secret != ABSENT_SECRET

            state_changes.append(
                ReceiveTransferCancelRoute(
                    transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
                )
            )

            # Currently, the only case where we can be initiators and not
            # know the secret is if the transfer is part of an atomic swap. In
            # the case of an atomic swap, we will not try to re-route the
            # transfer. In all other cases we can try to find another route
            # (and generate a new secret)
            if is_secret_known:
                state_changes.append(
                    ActionTransferReroute(
                        transfer=from_transfer,
                        balance_proof=from_transfer.balance_proof,  # pylint: disable=no-member
                        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
                        secret=random_secret(),
                    )
                )
        else:
            state_changes.append(
                ReceiveTransferRefund(
                    transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
                )
            )

        return state_changes
Esempio n. 4
0
def signed_transfer_from_description(
    private_key: PrivateKey,
    description: TransferDescriptionWithSecretState,
    channel: NettingChannelState,
    message_id: MessageID,
    block_number: BlockNumber,
    route_state: RouteState,
    route_states: List[RouteState],
) -> LockedTransferSignedState:
    send_locked_transfer = send_lockedtransfer(
        transfer_description=description,
        channel_state=channel,
        message_identifier=message_id,
        block_number=block_number,
        route_state=route_state,
        route_states=route_states,
    )
    message = message_from_sendevent(send_locked_transfer)
    assert isinstance(message, LockedTransfer), MYPY_ANNOTATION
    message.sign(LocalSigner(private_key))
    return lockedtransfersigned_from_message(message)