Beispiel #1
0
def test_get_channelstate_by_canonical_identifier():
    test_state = factories.make_chain_state(number_of_channels=3)
    canonical_identifier = test_state.channels[1].canonical_identifier

    assert (views.get_channelstate_by_canonical_identifier(
        chain_state=test_state.chain_state,
        canonical_identifier=canonical_identifier) == test_state.channels[1])
Beispiel #2
0
    def handle_contract_send_channelwithdraw(
        raiden: "RaidenService", channel_withdraw_event: ContractSendChannelWithdraw
    ) -> None:
        withdraw_confirmation_data = pack_withdraw(
            canonical_identifier=channel_withdraw_event.canonical_identifier,
            participant=raiden.address,
            total_withdraw=channel_withdraw_event.total_withdraw,
            expiration_block=channel_withdraw_event.expiration,
        )
        our_signature = raiden.signer.sign(data=withdraw_confirmation_data)

        chain_state = state_from_raiden(raiden)
        confirmed_block_identifier = chain_state.block_hash
        channel_state = get_channelstate_by_canonical_identifier(
            chain_state=chain_state,
            canonical_identifier=channel_withdraw_event.canonical_identifier,
        )

        if channel_state is None:
            raise RaidenUnrecoverableError("ContractSendChannelWithdraw for non-existing channel.")

        channel_proxy = raiden.proxy_manager.payment_channel(
            channel_state=channel_state, block_identifier=confirmed_block_identifier
        )

        try:
            channel_proxy.set_total_withdraw(
                total_withdraw=channel_withdraw_event.total_withdraw,
                expiration_block=channel_withdraw_event.expiration,
                participant_signature=our_signature,
                partner_signature=channel_withdraw_event.partner_signature,
                block_identifier=channel_withdraw_event.triggered_by_block_hash,
            )
        except InsufficientEth as e:
            raise RaidenUnrecoverableError(str(e)) from e
Beispiel #3
0
def channel_state_until_state_change(
    raiden: "RaidenService",
    canonical_identifier: CanonicalIdentifier,
    state_change_identifier: StateChangeID,
) -> Optional[NettingChannelState]:  # pragma: no unittest
    """ Go through WAL state changes until a certain balance hash is found. """
    assert raiden.wal, "Raiden has not been started yet"

    wal = restore_to_state_change(
        transition_function=node.state_transition,
        storage=raiden.wal.storage,
        state_change_identifier=state_change_identifier,
        node_address=raiden.address,
    )

    msg = "There is a state change, therefore the state must not be None"
    assert wal.state_manager.current_state is not None, msg

    chain_state = wal.state_manager.current_state

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state, canonical_identifier=canonical_identifier)

    if not channel_state:
        raise RaidenUnrecoverableError(
            f"Channel was not found before state_change {state_change_identifier}"
        )

    return channel_state
Beispiel #4
0
def update_path_finding_service_from_balance_proof(
    raiden: 'RaidenService',
    chain_state: 'ChainState',
    new_balance_proof: Union[BalanceProofSignedState,
                             BalanceProofUnsignedState],
) -> None:
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=new_balance_proof.canonical_identifier,
    )
    network_address = new_balance_proof.canonical_identifier.token_network_address
    error_msg = (f'tried to send a balance proof in non-existant channel '
                 f'token_network_address: {pex(network_address)} ')
    assert channel_state is not None, error_msg
    if isinstance(new_balance_proof, BalanceProofSignedState):
        assert channel_state.partner_state.balance_proof == new_balance_proof
    else:  # BalanceProofUnsignedState
        assert channel_state.our_state.balance_proof == new_balance_proof

    msg = UpdatePFS.from_channel_state(channel_state)
    msg.sign(raiden.signer)
    raiden.transport.send_global(constants.PATH_FINDING_BROADCASTING_ROOM, msg)
    log.debug(
        'Sent a PFS Update',
        message=msg,
        balance_proof=new_balance_proof,
    )
Beispiel #5
0
def send_pfs_update(
    raiden: "RaidenService",
    canonical_identifier: CanonicalIdentifier,
    update_fee_schedule: bool = False,
) -> None:
    if raiden.routing_mode == RoutingMode.PRIVATE:
        return

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=views.state_from_raiden(raiden), canonical_identifier=canonical_identifier
    )

    if channel_state is None:
        return

    capacity_msg = PFSCapacityUpdate.from_channel_state(channel_state)
    capacity_msg.sign(raiden.signer)
    raiden.transport.send_global(constants.PATH_FINDING_BROADCASTING_ROOM, capacity_msg)
    log.debug("Sent a PFS Capacity Update", message=capacity_msg, channel_state=channel_state)

    if update_fee_schedule:
        fee_msg = PFSFeeUpdate.from_channel_state(channel_state)
        fee_msg.sign(raiden.signer)

        raiden.transport.send_global(constants.PATH_FINDING_BROADCASTING_ROOM, fee_msg)
        log.debug("Sent a PFS Fee Update", message=fee_msg, channel_state=channel_state)
Beispiel #6
0
def handle_channel_update_transfer(raiden: "RaidenService", event: Event):
    token_network_identifier = event.originating_contract
    data = event.event_data
    args = data["args"]
    channel_identifier = args["channel_identifier"]
    transaction_hash = data["transaction_hash"]
    block_number = data["block_number"]
    block_hash = data["block_hash"]

    chain_state = views.state_from_raiden(raiden)
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_identifier,
            channel_identifier=channel_identifier,
        ),
    )

    if channel_state:
        channel_transfer_updated = ContractReceiveUpdateTransfer(
            transaction_hash=transaction_hash,
            canonical_identifier=channel_state.canonical_identifier,
            nonce=args["nonce"],
            block_number=block_number,
            block_hash=block_hash,
        )
        raiden.handle_and_track_state_change(channel_transfer_updated)
Beispiel #7
0
def subdispatch_targettask(
    chain_state: ChainState,
    state_change: StateChange,
    token_network_identifier: TokenNetworkID,
    channel_identifier: ChannelID,
    secrethash: SecretHash,
) -> TransitionResult[ChainState]:

    block_number = chain_state.block_number
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)

    if not sub_task:
        is_valid_subtask = True
        target_state = None

    elif sub_task and isinstance(sub_task, TargetTask):
        is_valid_subtask = (
            token_network_identifier == sub_task.token_network_identifier)
        target_state = sub_task.target_state
    else:
        is_valid_subtask = False

    events = list()
    channel_state = None
    if is_valid_subtask:
        channel_state = views.get_channelstate_by_canonical_identifier(
            chain_state=chain_state,
            canonical_identifier=CanonicalIdentifier(
                chain_identifier=chain_state.chain_id,
                token_network_address=token_network_identifier,
                channel_identifier=channel_identifier,
            ),
        )

    if channel_state:
        pseudo_random_generator = chain_state.pseudo_random_generator

        iteration = target.state_transition(
            target_state,
            state_change,
            channel_state,
            pseudo_random_generator,
            block_number,
        )
        events = iteration.events

        if iteration.new_state:
            sub_task = TargetTask(
                token_network_identifier,
                channel_identifier,
                iteration.new_state,
            )
            chain_state.payment_mapping.secrethashes_to_task[
                secrethash] = sub_task
        elif secrethash in chain_state.payment_mapping.secrethashes_to_task:
            del chain_state.payment_mapping.secrethashes_to_task[secrethash]

    return TransitionResult(chain_state, events)
Beispiel #8
0
def update_monitoring_service_from_balance_proof(
    raiden: 'RaidenService',
    chain_state: 'ChainState',
    new_balance_proof: BalanceProofSignedState,
) -> None:
    if raiden.config['services']['monitoring_enabled'] is False:
        return

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=new_balance_proof.canonical_identifier,
    )

    msg = (
        f'Failed to update monitoring service due to inability to find '
        f'channel: {new_balance_proof.channel_identifier} '
        f'token_network_address: {pex(new_balance_proof.token_network_identifier)}.'
    )
    assert channel_state, msg

    balance = channel.get_balance(
        sender=channel_state.our_state,
        receiver=channel_state.partner_state,
    )

    if balance < MONITORING_MIN_CAPACITY:
        log.warn(
            f'Skipping update to Monitoring service. '
            f'Available balance of {balance} is less than configured '
            f'minimum capacity of {MONITORING_MIN_CAPACITY}', )
        return

    rei_balance = raiden.user_deposit.effective_balance(
        raiden.address, 'latest')
    if rei_balance < MONITORING_REWARD:
        rdn_balance = to_rdn(rei_balance)
        rdn_reward = to_rdn(MONITORING_REWARD)
        log.warn(
            f'Skipping update to Monitoring service. '
            f'Your deposit balance {rdn_balance} is less than '
            f'the required monitoring service reward of {rdn_reward}', )
        return

    log.info(
        'Received new balance proof, creating message for Monitoring Service.',
        balance_proof=new_balance_proof,
    )

    monitoring_message = RequestMonitoring.from_balance_proof_signed_state(
        new_balance_proof,
        MONITORING_REWARD,
    )
    monitoring_message.sign(raiden.signer)
    raiden.transport.send_global(
        constants.MONITORING_BROADCASTING_ROOM,
        monitoring_message,
    )
Beispiel #9
0
def wait_for_channel_in_states(
    raiden: "RaidenService",
    payment_network_id: PaymentNetworkID,
    token_address: TokenAddress,
    channel_ids: List[ChannelID],
    retry_timeout: float,
    target_states: Sequence[str],
) -> None:
    """Wait until all channels are in `target_states`.

    Raises:
        ValueError: If the token_address is not registered in the
            payment_network.

    Note:
        This does not time out, use gevent.Timeout.
    """
    chain_state = views.state_from_raiden(raiden)
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_id,
        token_address=token_address)

    if token_network is None:
        raise ValueError(
            f"The token {token_address} is not registered on the network {payment_network_id}."
        )

    token_network_address = token_network.address

    list_cannonical_ids = [
        CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ) for channel_identifier in channel_ids
    ]

    while list_cannonical_ids:
        assert raiden, ALARM_TASK_ERROR_MSG
        assert raiden.alarm, ALARM_TASK_ERROR_MSG

        canonical_id = list_cannonical_ids[-1]
        chain_state = views.state_from_raiden(raiden)

        channel_state = views.get_channelstate_by_canonical_identifier(
            chain_state=chain_state, canonical_identifier=canonical_id)

        channel_is_settled = (channel_state is None
                              or channel.get_status(channel_state)
                              in target_states)

        if channel_is_settled:
            list_cannonical_ids.pop()
        else:
            gevent.sleep(retry_timeout)
Beispiel #10
0
    def handle_contract_send_channelclose(
        raiden: "RaidenService",
        chain_state: ChainState,
        channel_close_event: ContractSendChannelClose,
    ) -> None:
        balance_proof = channel_close_event.balance_proof

        if balance_proof:
            nonce = balance_proof.nonce
            balance_hash = balance_proof.balance_hash
            signature_in_proof = balance_proof.signature
            message_hash = balance_proof.message_hash
            canonical_identifier = balance_proof.canonical_identifier

        else:
            nonce = Nonce(0)
            balance_hash = EMPTY_BALANCE_HASH
            signature_in_proof = EMPTY_SIGNATURE
            message_hash = EMPTY_MESSAGE_HASH
            canonical_identifier = channel_close_event.canonical_identifier

        closing_data = pack_signed_balance_proof(
            msg_type=MessageTypeId.BALANCE_PROOF,
            nonce=nonce,
            balance_hash=balance_hash,
            additional_hash=message_hash,
            canonical_identifier=canonical_identifier,
            partner_signature=signature_in_proof,
        )

        our_signature = raiden.signer.sign(data=closing_data)

        confirmed_block_identifier = state_from_raiden(raiden).block_hash
        channel_state = get_channelstate_by_canonical_identifier(
            chain_state=chain_state,
            canonical_identifier=channel_close_event.canonical_identifier)

        if channel_state is None:
            raise RaidenUnrecoverableError(
                "ContractSendChannelClose for inexesting channel.")

        channel_proxy = raiden.proxy_manager.payment_channel(
            channel_state=channel_state,
            block_identifier=confirmed_block_identifier)

        channel_proxy.close(
            nonce=nonce,
            balance_hash=balance_hash,
            additional_hash=message_hash,
            non_closing_signature=signature_in_proof,
            closing_signature=our_signature,
            block_identifier=channel_close_event.triggered_by_block_hash,
        )
def handle_channel_new_balance(raiden: 'RaidenService', event: Event):
    data = event.event_data
    args = data['args']
    block_number = data['block_number']
    block_hash = data['block_hash']
    channel_identifier = args['channel_identifier']
    token_network_identifier = event.originating_contract
    participant_address = args['participant']
    total_deposit = args['total_deposit']
    transaction_hash = data['transaction_hash']

    chain_state = views.state_from_raiden(raiden)
    previous_channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_identifier,
            channel_identifier=channel_identifier,
        ),
    )

    # Channels will only be registered if this node is a participant
    if previous_channel_state is not None:
        previous_balance = previous_channel_state.our_state.contract_balance
        balance_was_zero = previous_balance == 0

        deposit_transaction = TransactionChannelNewBalance(
            participant_address,
            total_deposit,
            block_number,
        )

        newbalance_statechange = ContractReceiveChannelNewBalance(
            transaction_hash=transaction_hash,
            canonical_identifier=previous_channel_state.canonical_identifier,
            deposit_transaction=deposit_transaction,
            block_number=block_number,
            block_hash=block_hash,
        )
        raiden.handle_and_track_state_change(newbalance_statechange)

        if balance_was_zero and participant_address != raiden.address:
            connection_manager = raiden.connection_manager_for_token_network(
                token_network_identifier, )

            join_channel = gevent.spawn(
                connection_manager.join_channel,
                participant_address,
                total_deposit,
            )

            raiden.add_pending_greenlet(join_channel)
Beispiel #12
0
def update_monitoring_service_from_balance_proof(
    raiden: "RaidenService",
    chain_state: ChainState,
    new_balance_proof: BalanceProofSignedState,
    non_closing_participant: Address,
) -> None:
    if raiden.config.services.monitoring_enabled is False:
        return

    msg = f"Monitoring is enabled but the default monitoring service address is None."
    assert raiden.default_msc_address is not None, msg

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=new_balance_proof.canonical_identifier)

    msg = (
        f"Failed to update monitoring service due to inability to find "
        f"channel: {new_balance_proof.channel_identifier} "
        f"token_network_address: {to_checksum_address(new_balance_proof.token_network_address)}."
    )
    assert channel_state, msg

    msg = f"Monitoring is enabled but the `UserDeposit` contract is None."
    assert raiden.user_deposit is not None, msg
    rei_balance = raiden.user_deposit.effective_balance(
        raiden.address, BLOCK_ID_LATEST)
    if rei_balance < MONITORING_REWARD:
        rdn_balance = to_rdn(rei_balance)
        rdn_reward = to_rdn(MONITORING_REWARD)
        log.warning(f"Skipping update to Monitoring service. "
                    f"Your deposit balance {rdn_balance} is less than "
                    f"the required monitoring service reward of {rdn_reward}")
        return

    log.info(
        "Received new balance proof, creating message for Monitoring Service.",
        node=to_checksum_address(raiden.address),
        balance_proof=new_balance_proof,
    )

    monitoring_message = RequestMonitoring.from_balance_proof_signed_state(
        balance_proof=new_balance_proof,
        non_closing_participant=non_closing_participant,
        reward_amount=MONITORING_REWARD,
        monitoring_service_contract_address=raiden.default_msc_address,
    )
    monitoring_message.sign(raiden.signer)
    raiden.transport.broadcast(constants.MONITORING_BROADCASTING_ROOM,
                               monitoring_message)
Beispiel #13
0
    def handle_contract_send_channelupdate(
            raiden: "RaidenService",
            channel_update_event: ContractSendChannelUpdateTransfer) -> None:
        balance_proof = channel_update_event.balance_proof

        if balance_proof:
            canonical_identifier = balance_proof.canonical_identifier
            chain_state = state_from_raiden(raiden)
            confirmed_block_identifier = chain_state.block_hash

            channel_state = get_channelstate_by_canonical_identifier(
                chain_state=chain_state,
                canonical_identifier=canonical_identifier)

            if channel_state is None:
                raise RaidenUnrecoverableError(
                    "ContractSendChannelUpdateTransfer for inexesting channel."
                )

            channel = raiden.proxy_manager.payment_channel(
                channel_state=channel_state,
                block_identifier=confirmed_block_identifier)

            non_closing_data = pack_signed_balance_proof(
                msg_type=MessageTypeId.BALANCE_PROOF_UPDATE,
                nonce=balance_proof.nonce,
                balance_hash=balance_proof.balance_hash,
                additional_hash=balance_proof.message_hash,
                canonical_identifier=canonical_identifier,
                partner_signature=balance_proof.signature,
            )
            our_signature = raiden.signer.sign(data=non_closing_data)

            try:
                channel.update_transfer(
                    nonce=balance_proof.nonce,
                    balance_hash=balance_proof.balance_hash,
                    additional_hash=balance_proof.message_hash,
                    partner_signature=balance_proof.signature,
                    signature=our_signature,
                    block_identifier=channel_update_event.
                    triggered_by_block_hash,
                )
            except InsufficientEth as e:
                raise RaidenUnrecoverableError(
                    f"{str(e)}\n"
                    "CAUTION: This happened when updating our side of the channel "
                    "during a channel settlement. You are in immediate danger of "
                    "losing funds in this channel.") from e
Beispiel #14
0
def get_contractreceiveupdatetransfer_data_from_event(
    chain_state: ChainState, event: DecodedEvent
) -> Optional[NettingChannelState]:
    data = event.event_data
    args = data["args"]
    channel_identifier = args["channel_identifier"]
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=TokenNetworkAddress(event.originating_contract),
            channel_identifier=channel_identifier,
        ),
    )
    return channel_state
Beispiel #15
0
def channel_state_until_state_change(
    raiden,
    payment_network_identifier: typing.PaymentNetworkID,
    token_address: typing.TokenAddress,
    channel_identifier: typing.ChannelID,
    state_change_identifier: int,
) -> typing.Optional[NettingChannelState]:
    """ Go through WAL state changes until a certain balance hash is found. """
    wal = restore_to_state_change(
        transition_function=node.state_transition,
        storage=raiden.wal.storage,
        state_change_identifier=state_change_identifier,
    )

    msg = 'There is a state change, therefore the state must not be None'
    assert wal.state_manager.current_state is not None, msg

    chain_state = wal.state_manager.current_state
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        payment_network_id=payment_network_identifier,
        token_address=token_address,
    )

    if not token_network:
        return None

    token_network_address = token_network.address

    canonical_identifier = CanonicalIdentifier(
        chain_identifier=chain_state.chain_id,
        token_network_address=token_network_address,
        channel_identifier=channel_identifier,
    )
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=wal.state_manager.current_state,
        canonical_identifier=canonical_identifier,
    )

    if not channel_state:
        raise RaidenUnrecoverableError(
            f"Channel was not found before state_change {state_change_identifier}",
        )

    return channel_state
Beispiel #16
0
def handle_channel_closed(raiden: "RaidenService", event: Event):
    token_network_identifier = event.originating_contract
    data = event.event_data
    block_number = data["block_number"]
    args = data["args"]
    channel_identifier = args["channel_identifier"]
    transaction_hash = data["transaction_hash"]
    block_hash = data["block_hash"]

    chain_state = views.state_from_raiden(raiden)
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_identifier,
            channel_identifier=channel_identifier,
        ),
    )

    channel_closed: StateChange
    if channel_state:
        # The from address is included in the ChannelClosed event as the
        # closing_participant field
        channel_closed = ContractReceiveChannelClosed(
            transaction_hash=transaction_hash,
            transaction_from=args["closing_participant"],
            canonical_identifier=channel_state.canonical_identifier,
            block_number=block_number,
            block_hash=block_hash,
        )
        raiden.handle_and_track_state_change(channel_closed)
    else:
        # This is a channel close event of a channel we're not a participant of
        route_closed = ContractReceiveRouteClosed(
            transaction_hash=transaction_hash,
            canonical_identifier=CanonicalIdentifier(
                chain_identifier=chain_state.chain_id,
                token_network_address=token_network_identifier,
                channel_identifier=channel_identifier,
            ),
            block_number=block_number,
            block_hash=block_hash,
        )
        raiden.handle_and_track_state_change(route_closed)
Beispiel #17
0
def get_contractreceivechannelclosed_data_from_event(
        chain_state: "ChainState",
        event: DecodedEvent) -> Optional[CanonicalIdentifier]:
    token_network_address = TokenNetworkAddress(event.originating_contract)
    data = event.event_data
    args = data["args"]
    channel_identifier = args["channel_identifier"]

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ),
    )

    if channel_state:
        return channel_state.canonical_identifier

    return None
Beispiel #18
0
def handle_contract_receive_channel_closed(
    chain_state: ChainState, state_change: ContractReceiveChannelClosed
) -> TransitionResult[ChainState]:
    # cleanup queue for channel
    canonical_identifier = CanonicalIdentifier(
        chain_identifier=chain_state.chain_id,
        token_network_address=state_change.token_network_address,
        channel_identifier=state_change.channel_identifier,
    )
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state, canonical_identifier=canonical_identifier
    )
    if channel_state:
        queue_id = QueueIdentifier(
            recipient=channel_state.partner_state.address,
            canonical_identifier=canonical_identifier,
        )
        if queue_id in chain_state.queueids_to_queues:
            chain_state.queueids_to_queues.pop(queue_id)

    return handle_token_network_action(chain_state=chain_state, state_change=state_change)
Beispiel #19
0
def channel_state_until_state_change(
        raiden, canonical_identifier: CanonicalIdentifier,
        state_change_identifier: int) -> typing.Optional[NettingChannelState]:
    """ Go through WAL state changes until a certain balance hash is found. """
    wal = restore_to_state_change(
        transition_function=node.state_transition,
        storage=raiden.wal.storage,
        state_change_identifier=state_change_identifier,
    )

    msg = "There is a state change, therefore the state must not be None"
    assert wal.state_manager.current_state is not None, msg

    chain_state = wal.state_manager.current_state
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state, canonical_identifier=canonical_identifier)

    if not channel_state:
        raise RaidenUnrecoverableError(
            f"Channel was not found before state_change {state_change_identifier}"
        )

    return channel_state
Beispiel #20
0
def payment_channel_open_and_deposit(
    app0: App,
    app1: App,
    token_address: TokenAddress,
    deposit: TokenAmount,
    settle_timeout: BlockTimeout,
) -> None:
    """ Open a new channel with app0 and app1 as participants """
    assert token_address

    block_identifier: BlockIdentifier
    if app0.raiden.wal:
        block_identifier = views.get_confirmed_blockhash(app0.raiden)
    else:
        block_identifier = BLOCK_ID_LATEST
    token_network_address = app0.raiden.default_registry.get_token_network(
        token_address=token_address, block_identifier=block_identifier)
    assert token_network_address, "request a channel for an unregistered token"
    token_network_proxy = app0.raiden.proxy_manager.token_network(
        token_network_address, block_identifier=BLOCK_ID_LATEST)

    channel_identifier, _, _ = token_network_proxy.new_netting_channel(
        partner=app1.raiden.address,
        settle_timeout=settle_timeout,
        given_block_identifier=block_identifier,
    )
    assert channel_identifier

    if deposit != 0:
        for app, partner in [(app0, app1), (app1, app0)]:
            waiting.wait_for_newchannel(
                raiden=app.raiden,
                token_network_registry_address=app.raiden.default_registry.
                address,
                token_address=token_address,
                partner_address=partner.raiden.address,
                retry_timeout=0.5,
            )

            chain_state = state_from_raiden(app.raiden)
            canonical_identifier = CanonicalIdentifier(
                chain_identifier=chain_state.chain_id,
                token_network_address=token_network_proxy.address,
                channel_identifier=channel_identifier,
            )
            channel_state = get_channelstate_by_canonical_identifier(
                chain_state=chain_state,
                canonical_identifier=canonical_identifier)
            assert channel_state, "nodes dont share a channel"

            # Use each app's own chain because of the private key / local signing
            token = app.raiden.proxy_manager.token(token_address,
                                                   BLOCK_ID_LATEST)
            payment_channel_proxy = app.raiden.proxy_manager.payment_channel(
                channel_state=channel_state, block_identifier=BLOCK_ID_LATEST)

            # This check can succeed and the deposit still fail, if channels are
            # openned in parallel
            previous_balance = token.balance_of(app.raiden.address)
            assert previous_balance >= deposit

            # the payment channel proxy will call approve
            # token.approve(token_network_proxy.address, deposit)
            payment_channel_proxy.approve_and_set_total_deposit(
                total_deposit=deposit, block_identifier=BLOCK_ID_LATEST)

            # Balance must decrease by at least but not exactly `deposit` amount,
            # because channels can be openned in parallel
            new_balance = token.balance_of(app.raiden.address)
            assert new_balance <= previous_balance - deposit

        check_channel(app0, app1, token_network_proxy.address, settle_timeout,
                      deposit)
Beispiel #21
0
    def handle_contract_send_channelsettle(
            raiden: "RaidenService",
            channel_settle_event: ContractSendChannelSettle) -> None:
        assert raiden.wal, "The Raiden Service must be initialize to handle events"

        canonical_identifier = CanonicalIdentifier(
            chain_identifier=raiden.rpc_client.chain_id,
            token_network_address=channel_settle_event.token_network_address,
            channel_identifier=channel_settle_event.channel_identifier,
        )
        triggered_by_block_hash = channel_settle_event.triggered_by_block_hash

        chain_state = state_from_raiden(raiden)
        channel_state = get_channelstate_by_canonical_identifier(
            chain_state=chain_state, canonical_identifier=canonical_identifier)

        if channel_state is None:
            raise RaidenUnrecoverableError(
                "ContractSendChannelSettle for inexesting channel.")

        confirmed_block_identifier = chain_state.block_hash
        payment_channel: PaymentChannel = raiden.proxy_manager.payment_channel(
            channel_state=channel_state,
            block_identifier=confirmed_block_identifier)
        token_network_proxy: TokenNetwork = payment_channel.token_network

        try:
            participants_details = token_network_proxy.detail_participants(
                participant1=payment_channel.participant1,
                participant2=payment_channel.participant2,
                block_identifier=triggered_by_block_hash,
                channel_identifier=channel_settle_event.channel_identifier,
            )
        except ValueError:
            # The triggered_by_block_hash block was pruned.
            participants_details = token_network_proxy.detail_participants(
                participant1=payment_channel.participant1,
                participant2=payment_channel.participant2,
                block_identifier=BLOCK_ID_LATEST,
                channel_identifier=channel_settle_event.channel_identifier,
            )

        our_details = participants_details.our_details
        partner_details = participants_details.partner_details

        log_details = {
            "chain_id": canonical_identifier.chain_identifier,
            "token_network_address":
            canonical_identifier.token_network_address,
            "channel_identifier": canonical_identifier.channel_identifier,
            "node": to_checksum_address(raiden.address),
            "partner": to_checksum_address(partner_details.address),
            "our_deposit": our_details.deposit,
            "our_withdrawn": our_details.withdrawn,
            "our_is_closer": our_details.is_closer,
            "our_balance_hash": to_hex(our_details.balance_hash),
            "our_nonce": our_details.nonce,
            "our_locksroot": to_hex(our_details.locksroot),
            "our_locked_amount": our_details.locked_amount,
            "partner_deposit": partner_details.deposit,
            "partner_withdrawn": partner_details.withdrawn,
            "partner_is_closer": partner_details.is_closer,
            "partner_balance_hash": to_hex(partner_details.balance_hash),
            "partner_nonce": partner_details.nonce,
            "partner_locksroot": to_hex(partner_details.locksroot),
            "partner_locked_amount": partner_details.locked_amount,
        }

        if our_details.balance_hash != EMPTY_BALANCE_HASH:
            event_record = get_event_with_balance_proof_by_balance_hash(
                storage=raiden.wal.storage,
                canonical_identifier=canonical_identifier,
                balance_hash=our_details.balance_hash,
                recipient=participants_details.partner_details.address,
            )

            if event_record is None:
                log.critical("our balance proof not found", **log_details)
                raise RaidenUnrecoverableError(
                    "Our balance proof could not be found in the database")

            our_balance_proof = event_record.data.balance_proof  # type: ignore
            our_transferred_amount = our_balance_proof.transferred_amount
            our_locked_amount = our_balance_proof.locked_amount
            our_locksroot = our_balance_proof.locksroot
        else:
            our_transferred_amount = 0
            our_locked_amount = 0
            our_locksroot = LOCKSROOT_OF_NO_LOCKS

        if partner_details.balance_hash != EMPTY_BALANCE_HASH:
            state_change_record = get_state_change_with_balance_proof_by_balance_hash(
                storage=raiden.wal.storage,
                canonical_identifier=canonical_identifier,
                balance_hash=partner_details.balance_hash,
                sender=participants_details.partner_details.address,
            )
            if state_change_record is None:
                log.critical("partner balance proof not found", **log_details)
                raise RaidenUnrecoverableError(
                    "Partner balance proof could not be found in the database")

            partner_balance_proof = state_change_record.data.balance_proof  # type: ignore
            partner_transferred_amount = partner_balance_proof.transferred_amount
            partner_locked_amount = partner_balance_proof.locked_amount
            partner_locksroot = partner_balance_proof.locksroot
        else:
            partner_transferred_amount = 0
            partner_locked_amount = 0
            partner_locksroot = LOCKSROOT_OF_NO_LOCKS

        try:
            payment_channel.settle(
                transferred_amount=our_transferred_amount,
                locked_amount=our_locked_amount,
                locksroot=our_locksroot,
                partner_transferred_amount=partner_transferred_amount,
                partner_locked_amount=partner_locked_amount,
                partner_locksroot=partner_locksroot,
                block_identifier=triggered_by_block_hash,
            )
        except InsufficientEth as e:
            raise RaidenUnrecoverableError(str(e)) from e
def handle_channel_settled(raiden: 'RaidenService', event: Event):
    data = event.event_data
    token_network_identifier = event.originating_contract
    channel_identifier = data['args']['channel_identifier']
    block_number = data['block_number']
    block_hash = data['block_hash']
    transaction_hash = data['transaction_hash']

    chain_state = views.state_from_raiden(raiden)
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_identifier,
            channel_identifier=channel_identifier,
        ),
    )

    # This may happen for two reasons:
    # - This node is not a participant for the given channel (normal operation,
    #   the event should be ignored).
    # - Something went wrong in our code and the channel state was cleared
    #   before settle (a bug, this should raise an exception on development
    #   mode).
    # Because we cannot distinguish the two cases, assume the channel is not of
    # interest and ignore the event.
    if not channel_state:
        return
    """
    This is resolving a corner case where the current node view
    of the channel state does not reflect what the blockchain
    contains.
    The corner case goes as follows in a setup of nodes:
    A -> B:
    - A sends out a LockedTransfer to B
    - B sends a refund to A
    - B goes offline
    - A sends LockExpired to B
      Here:
      (1) the lock is removed from A's state
      (2) B never received the message
    - A closes the channel with B's refund
    - B comes back online and calls updateNonClosingBalanceProof
      with A's LockedTransfer (LockExpired was never processed).
    - When channel is settled, B unlocks it's refund transfer lock
      provided that it gains from doing so.
    - A does NOT try to unlock its lock because its side
      of the channel state is empty (lock expired and was removed).

    The above is resolved by providing the state machine with the
    onchain locksroots for both participants in the channel so that
    the channel state is updated to store these locksroots.
    In `raiden_event_handler:handle_contract_send_channelunlock`,
    those values are used to restore the channel state back to where
    the locksroots values existed and this channel state is used
    to calculate the gain and potentially perform unlocks in case
    there is value to be gained.
    """
    canonical_identifier = CanonicalIdentifier(
        chain_identifier=CHAIN_ID_UNSPECIFIED,
        token_network_address=token_network_identifier,
        channel_identifier=channel_identifier,
    )
    our_locksroot, partner_locksroot = get_onchain_locksroots(
        chain=raiden.chain,
        canonical_identifier=canonical_identifier,
        participant1=channel_state.our_state.address,
        participant2=channel_state.partner_state.address,
        block_identifier=block_hash,
    )

    channel_settled = ContractReceiveChannelSettled(
        transaction_hash=transaction_hash,
        canonical_identifier=channel_state.canonical_identifier,
        our_onchain_locksroot=our_locksroot,
        partner_onchain_locksroot=partner_locksroot,
        block_number=block_number,
        block_hash=block_hash,
    )
    raiden.handle_and_track_state_change(channel_settled)
Beispiel #23
0
def wait_for_channel_in_states(
    raiden: "RaidenService",
    token_network_registry_address: TokenNetworkRegistryAddress,
    token_address: TokenAddress,
    channel_ids: List[ChannelID],
    retry_timeout: float,
    target_states: Sequence[ChannelState],
) -> None:
    """Wait until all channels are in `target_states`.

    Raises:
        ValueError: If the token_address is not registered in the
            token_network_registry.

    Note:
        This does not time out, use gevent.Timeout.
    """
    chain_state = views.state_from_raiden(raiden)
    token_network = views.get_token_network_by_token_address(
        chain_state=chain_state,
        token_network_registry_address=token_network_registry_address,
        token_address=token_address,
    )

    if token_network is None:
        raise ValueError(
            f"The token {to_checksum_address(token_address)} is not registered on "
            f"the network {to_checksum_address(token_network_registry_address)}."
        )

    token_network_address = token_network.address

    list_cannonical_ids = [
        CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ) for channel_identifier in channel_ids
    ]

    log_details = {
        "token_network_registry_address":
        to_checksum_address(token_network_registry_address),
        "token_address":
        to_checksum_address(token_address),
        "list_cannonical_ids":
        list_cannonical_ids,
        "target_states":
        target_states,
    }

    while list_cannonical_ids:
        assert raiden, ALARM_TASK_ERROR_MSG
        assert raiden.alarm, ALARM_TASK_ERROR_MSG

        canonical_id = list_cannonical_ids[-1]
        chain_state = views.state_from_raiden(raiden)

        channel_state = views.get_channelstate_by_canonical_identifier(
            chain_state=chain_state, canonical_identifier=canonical_id)

        channel_is_settled = (channel_state is None
                              or channel.get_status(channel_state)
                              in target_states)

        if channel_is_settled:
            list_cannonical_ids.pop()
        else:
            log.debug("wait_for_channel_in_states", **log_details)
            gevent.sleep(retry_timeout)
Beispiel #24
0
def get_contractreceivechannelsettled_data_from_event(
    proxy_manager: ProxyManager,
    chain_state: ChainState,
    event: DecodedEvent,
    current_confirmed_head: BlockNumber,
) -> Optional[ChannelSettleState]:
    data = event.event_data
    token_network_address = TokenNetworkAddress(event.originating_contract)
    channel_identifier = data["args"]["channel_identifier"]
    block_hash = data["block_hash"]

    canonical_identifier = CanonicalIdentifier(
        chain_identifier=chain_state.chain_id,
        token_network_address=token_network_address,
        channel_identifier=channel_identifier,
    )

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state, canonical_identifier=canonical_identifier)

    # This may happen for two reasons:
    # - This node is not a participant for the given channel (normal operation,
    #   the event should be ignored).
    # - Something went wrong in our code and the channel state was cleared
    #   before settle (a bug, this should raise an exception on development
    #   mode).
    # Because we cannot distinguish the two cases, assume the channel is not of
    # interest and ignore the event.
    if not channel_state:
        return None

    # Recover the locksroot from the blockchain to fix data races. Check
    # get_onchain_locksroots for details.
    try:
        # First try to query the unblinded state. This way the
        # ContractReceiveChannelSettled's locksroots will  match the values
        # provided during settle.
        our_locksroot, partner_locksroot = get_onchain_locksroots(
            proxy_manager=proxy_manager,
            channel_state=channel_state,
            participant1=channel_state.our_state.address,
            participant2=channel_state.partner_state.address,
            block_identifier=block_hash,
        )
    except ValueError:
        # State pruning handling. The block which generate the
        # ChannelSettled event may have been pruned, because of this the
        # RPC call raised ValueError.
        #
        # The solution is to query the channel's state from the latest
        # *confirmed* block, this /may/ create a ContractReceiveChannelSettled
        # with the wrong locksroot (i.e. not the locksroot used during the call
        # to settle). However this is fine, because at this point the channel
        # is settled, it is known that the locksroot can not be reverted
        # without an unlock, and because the unlocks are fair it doesn't matter
        # who called it, only if there are tokens locked in the settled
        # channel.
        our_locksroot, partner_locksroot = get_onchain_locksroots(
            proxy_manager=proxy_manager,
            channel_state=channel_state,
            participant1=channel_state.our_state.address,
            participant2=channel_state.partner_state.address,
            block_identifier=current_confirmed_head,
        )

    return ChannelSettleState(canonical_identifier, our_locksroot,
                              partner_locksroot)
Beispiel #25
0
    def handle_contract_send_channelunlock(
        raiden: "RaidenService",
        chain_state: ChainState,
        channel_unlock_event: ContractSendChannelBatchUnlock,
    ) -> None:
        assert raiden.wal, "The Raiden Service must be initialize to handle events"

        canonical_identifier = channel_unlock_event.canonical_identifier
        token_network_address = canonical_identifier.token_network_address
        channel_identifier = canonical_identifier.channel_identifier
        participant = channel_unlock_event.sender

        channel_state = get_channelstate_by_canonical_identifier(
            chain_state=state_from_raiden(raiden),
            canonical_identifier=canonical_identifier)
        if channel_state is None:
            raise RaidenUnrecoverableError(
                "ContractSendChannelBatchUnlock for inexesting channel.")

        confirmed_block_identifier = state_from_raiden(raiden).block_hash
        payment_channel: PaymentChannel = raiden.proxy_manager.payment_channel(
            channel_state=channel_state,
            block_identifier=confirmed_block_identifier)

        channel_state = get_channelstate_by_token_network_and_partner(
            chain_state=chain_state,
            token_network_address=token_network_address,
            partner_address=participant,
        )

        if not channel_state:
            # channel was cleaned up already due to an unlock
            raise RaidenUnrecoverableError(
                f"Failed to find channel state with partner:"
                f"{to_checksum_address(participant)}, "
                f"token_network:{to_checksum_address(token_network_address)}")

        our_address = channel_state.our_state.address
        our_locksroot = channel_state.our_state.onchain_locksroot

        partner_address = channel_state.partner_state.address
        partner_locksroot = channel_state.partner_state.onchain_locksroot

        # we want to unlock because there are on-chain unlocked locks
        search_events = our_locksroot != LOCKSROOT_OF_NO_LOCKS
        # we want to unlock, because there are unlocked/unclaimed locks
        search_state_changes = partner_locksroot != LOCKSROOT_OF_NO_LOCKS

        if not search_events and not search_state_changes:
            # In the case that someone else sent the unlock we do nothing
            # Check https://github.com/raiden-network/raiden/issues/3152
            # for more details
            log.warning(
                "Onchain unlock already mined",
                canonical_identifier=canonical_identifier,
                channel_identifier=canonical_identifier.channel_identifier,
                participant=to_checksum_address(participant),
            )
            return

        if search_state_changes:
            state_change_record = get_state_change_with_balance_proof_by_locksroot(
                storage=raiden.wal.storage,
                canonical_identifier=canonical_identifier,
                locksroot=partner_locksroot,
                sender=partner_address,
            )

            if state_change_record is None:
                raise RaidenUnrecoverableError(
                    f"Failed to find state that matches the current channel locksroots. "
                    f"chain_id:{raiden.rpc_client.chain_id} "
                    f"token_network:{to_checksum_address(token_network_address)} "
                    f"channel:{channel_identifier} "
                    f"participant:{to_checksum_address(participant)} "
                    f"our_locksroot:{to_hex(our_locksroot)} "
                    f"partner_locksroot:{to_hex(partner_locksroot)} ")

            state_change_identifier = state_change_record.state_change_identifier
            restored_channel_state = channel_state_until_state_change(
                raiden=raiden,
                canonical_identifier=canonical_identifier,
                state_change_identifier=state_change_identifier,
            )

            gain = get_batch_unlock_gain(restored_channel_state)

            skip_unlock = (restored_channel_state.partner_state.address
                           == participant and gain.from_partner_locks == 0)
            if not skip_unlock:
                unlock(
                    payment_channel=payment_channel,
                    end_state=restored_channel_state.partner_state,
                    sender=partner_address,
                    receiver=our_address,
                    given_block_identifier=channel_unlock_event.
                    triggered_by_block_hash,
                )

        if search_events:
            event_record = get_event_with_balance_proof_by_locksroot(
                storage=raiden.wal.storage,
                canonical_identifier=canonical_identifier,
                locksroot=our_locksroot,
                recipient=partner_address,
            )

            if event_record is None:
                raise RaidenUnrecoverableError(
                    f"Failed to find event that match current channel locksroots. "
                    f"chain_id:{raiden.rpc_client.chain_id} "
                    f"token_network:{to_checksum_address(token_network_address)} "
                    f"channel:{channel_identifier} "
                    f"participant:{to_checksum_address(participant)} "
                    f"our_locksroot:{to_hex(our_locksroot)} "
                    f"partner_locksroot:{to_hex(partner_locksroot)} ")

            state_change_identifier = event_record.state_change_identifier
            restored_channel_state = channel_state_until_state_change(
                raiden=raiden,
                canonical_identifier=canonical_identifier,
                state_change_identifier=state_change_identifier,
            )

            gain = get_batch_unlock_gain(restored_channel_state)

            skip_unlock = (restored_channel_state.our_state.address
                           == participant and gain.from_our_locks == 0)
            if not skip_unlock:
                try:
                    unlock(
                        payment_channel=payment_channel,
                        end_state=restored_channel_state.our_state,
                        sender=our_address,
                        receiver=partner_address,
                        given_block_identifier=channel_unlock_event.
                        triggered_by_block_hash,
                    )
                except InsufficientEth as e:
                    raise RaidenUnrecoverableError(str(e)) from e
Beispiel #26
0
def handle_channel_settled(raiden: "RaidenService", event: Event):
    data = event.event_data
    token_network_identifier = event.originating_contract
    channel_identifier = data["args"]["channel_identifier"]
    block_number = data["block_number"]
    block_hash = data["block_hash"]
    transaction_hash = data["transaction_hash"]

    chain_state = views.state_from_raiden(raiden)
    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=token_network_identifier,
            channel_identifier=channel_identifier,
        ),
    )

    # This may happen for two reasons:
    # - This node is not a participant for the given channel (normal operation,
    #   the event should be ignored).
    # - Something went wrong in our code and the channel state was cleared
    #   before settle (a bug, this should raise an exception on development
    #   mode).
    # Because we cannot distinguish the two cases, assume the channel is not of
    # interest and ignore the event.
    if not channel_state:
        return

    # Recover the locksroot from the blockchain to fix data races. Check
    # get_onchain_locksroots for details.
    try:
        # First try to query the unblinded state. This way the
        # ContractReceiveChannelSettled's locksroots will  match the values
        # provided during settle.
        our_locksroot, partner_locksroot = get_onchain_locksroots(
            chain=raiden.chain,
            canonical_identifier=channel_state.canonical_identifier,
            participant1=channel_state.our_state.address,
            participant2=channel_state.partner_state.address,
            block_identifier=block_hash,
        )
    except ValueError:
        # State pruning handling. The block which generate the ChannelSettled
        # event may have been pruned, because of this the RPC call will raises
        # a ValueError.
        #
        # The solution is to query the channel's state from the latest block,
        # this /may/ create a ContractReceiveChannelSettled with the wrong
        # locksroot (i.e. not the locksroot used during the call to settle).
        # However this is fine, because at this point the channel is settled,
        # it is known that the locksroot can not be reverted without an unlock,
        # and because the unlocks are fare it doesn't matter who called it,
        # only if there are tokens locked in the settled channel.
        our_locksroot, partner_locksroot = get_onchain_locksroots(
            chain=raiden.chain,
            canonical_identifier=channel_state.canonical_identifier,
            participant1=channel_state.our_state.address,
            participant2=channel_state.partner_state.address,
            block_identifier="latest",
        )

    channel_settled = ContractReceiveChannelSettled(
        transaction_hash=transaction_hash,
        canonical_identifier=channel_state.canonical_identifier,
        our_onchain_locksroot=our_locksroot,
        partner_onchain_locksroot=partner_locksroot,
        block_number=block_number,
        block_hash=block_hash,
    )
    raiden.handle_and_track_state_change(channel_settled)
Beispiel #27
0
def update_monitoring_service_from_balance_proof(
    raiden: "RaidenService",
    chain_state: ChainState,
    new_balance_proof: BalanceProofSignedState,
    non_closing_participant: Address,
) -> None:
    if raiden.config.services.monitoring_enabled is False:
        return

    msg = "Monitoring is enabled but the default monitoring service address is None."
    assert raiden.default_msc_address is not None, msg

    channel_state = views.get_channelstate_by_canonical_identifier(
        chain_state=chain_state,
        canonical_identifier=new_balance_proof.canonical_identifier)

    msg = (
        f"Failed to update monitoring service due to inability to find "
        f"channel: {new_balance_proof.channel_identifier} "
        f"token_network_address: {to_checksum_address(new_balance_proof.token_network_address)}."
    )
    assert channel_state, msg

    msg = "Monitoring is enabled but the `UserDeposit` contract is None."
    assert raiden.default_user_deposit is not None, msg
    rei_balance = raiden.default_user_deposit.effective_balance(
        raiden.address, BLOCK_ID_LATEST)
    if rei_balance < MONITORING_REWARD:
        rdn_balance = to_rdn(rei_balance)
        rdn_reward = to_rdn(MONITORING_REWARD)
        log.warning(f"Skipping update to Monitoring service. "
                    f"Your deposit balance {rdn_balance} is less than "
                    f"the required monitoring service reward of {rdn_reward}")
        return

    # In production there should be no MonitoringRequest if
    # channel balance is below a certain threshold. This is
    # a naive approach that needs to be worked on in the future
    if raiden.config.environment_type == Environment.PRODUCTION:
        message = ("Skipping update to Monitoring service. "
                   "Your channel balance {channel_balance} is less than "
                   "the required minimum balance of {min_balance} ")

        dai_token_network_address = views.get_token_network_address_by_token_address(
            chain_state=chain_state,
            token_network_registry_address=raiden.default_registry.address,
            token_address=DAI_TOKEN_ADDRESS,
        )
        weth_token_network_address = views.get_token_network_address_by_token_address(
            chain_state=chain_state,
            token_network_registry_address=raiden.default_registry.address,
            token_address=WETH_TOKEN_ADDRESS,
        )
        channel_balance = get_balance(
            sender=channel_state.our_state,
            receiver=channel_state.partner_state,
        )

        if channel_state.canonical_identifier.token_network_address == dai_token_network_address:
            if channel_balance < MIN_MONITORING_AMOUNT_DAI:
                data = dict(
                    channel_balance=channel_balance,
                    min_balance=MIN_MONITORING_AMOUNT_DAI,
                    channel_id=channel_state.canonical_identifier.
                    channel_identifier,
                    token_address=to_checksum_address(DAI_TOKEN_ADDRESS),
                )
                log.warning(message.format(**data), **data)
                return
        if channel_state.canonical_identifier.token_network_address == weth_token_network_address:
            if channel_balance < MIN_MONITORING_AMOUNT_WETH:
                data = dict(
                    channel_balance=channel_balance,
                    min_balance=MIN_MONITORING_AMOUNT_WETH,
                    channel_id=channel_state.canonical_identifier.
                    channel_identifier,
                    token_address=to_checksum_address(WETH_TOKEN_ADDRESS),
                )
                log.warning(message.format(**data), **data)
                return

    log.info(
        "Received new balance proof, creating message for Monitoring Service.",
        node=to_checksum_address(raiden.address),
        balance_proof=new_balance_proof,
    )

    monitoring_message = RequestMonitoring.from_balance_proof_signed_state(
        balance_proof=new_balance_proof,
        non_closing_participant=non_closing_participant,
        reward_amount=MONITORING_REWARD,
        monitoring_service_contract_address=raiden.default_msc_address,
    )
    monitoring_message.sign(raiden.signer)
    raiden.transport.broadcast(constants.MONITORING_BROADCASTING_ROOM,
                               monitoring_message)
Beispiel #28
0
def subdispatch_to_paymenttask(
        chain_state: ChainState, state_change: StateChange,
        secrethash: SecretHash) -> TransitionResult[ChainState]:
    block_number = chain_state.block_number
    block_hash = chain_state.block_hash
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events: List[Event] = list()

    if sub_task:
        pseudo_random_generator = chain_state.pseudo_random_generator
        sub_iteration: Union[TransitionResult[InitiatorPaymentState],
                             TransitionResult[MediatorTransferState],
                             TransitionResult[TargetTransferState], ]

        if isinstance(sub_task, InitiatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = get_token_network_by_address(
                chain_state, token_network_identifier)
            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

        elif isinstance(sub_task, MediatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = get_token_network_by_address(
                chain_state, token_network_identifier)

            if token_network_state:
                channelids_to_channels = token_network_state.channelidentifiers_to_channels
                sub_iteration = mediator.state_transition(
                    mediator_state=sub_task.mediator_state,
                    state_change=state_change,
                    channelidentifiers_to_channels=channelids_to_channels,
                    nodeaddresses_to_networkstates=chain_state.
                    nodeaddresses_to_networkstates,
                    pseudo_random_generator=pseudo_random_generator,
                    block_number=block_number,
                    block_hash=block_hash,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

        elif isinstance(sub_task, TargetTask):
            token_network_identifier = sub_task.token_network_identifier
            channel_identifier = sub_task.channel_identifier

            channel_state = views.get_channelstate_by_canonical_identifier(
                chain_state=chain_state,
                canonical_identifier=CanonicalIdentifier(
                    chain_identifier=chain_state.chain_id,
                    token_network_address=token_network_identifier,
                    channel_identifier=channel_identifier,
                ),
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    target_state=sub_task.target_state,
                    state_change=state_change,
                    channel_state=channel_state,
                    pseudo_random_generator=pseudo_random_generator,
                    block_number=block_number,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

    return TransitionResult(chain_state, events)