def test_action_claim_reward_triggered_event_handler_without_update_state_doesnt_trigger_claim_call(  # noqa
        context: Context, ):
    """ Tests that `claimReward` is called when the ActionMonitoringTriggeredEvent is triggered and
    user has sufficient balance in user deposit contract
    """
    context = setup_state_with_closed_channel(context)

    context.db.upsert_monitor_request(
        get_signed_monitor_request(nonce=Nonce(6),
                                   reward_amount=TokenAmount(0)))

    trigger_event = ActionClaimRewardTriggeredEvent(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        channel_identifier=DEFAULT_CHANNEL_IDENTIFIER,
        non_closing_participant=DEFAULT_PARTICIPANT2,
    )

    channel = context.db.get_channel(trigger_event.token_network_address,
                                     trigger_event.channel_identifier)
    assert channel
    assert channel.claim_tx_hash is None

    # Set update state
    channel.update_status = OnChainUpdateStatus(
        update_sender_address=Address('0x' + '1' * 40), nonce=Nonce(6))
    context.db.upsert_channel(channel)

    action_claim_reward_triggered_event_handler(trigger_event, context)

    # check that the monitor call has been done
    assert context.monitoring_service_contract.functions.claimReward.called is False
Example #2
0
def monitor_new_balance_proof_event_handler(event: Event,
                                            context: Context) -> None:
    assert isinstance(event, ReceiveMonitoringNewBalanceProofEvent)
    channel = context.database.get_channel(event.token_network_address,
                                           event.channel_identifier)

    if channel is None:
        log.error(
            "Channel not in database",
            token_network_address=event.token_network_address,
            identifier=event.channel_identifier,
        )
        metrics.get_metrics_for_label(metrics.ERRORS_LOGGED,
                                      metrics.ErrorCategory.STATE).inc()
        return

    log.info(
        "Received MSC NewBalanceProof event",
        token_network_address=event.token_network_address,
        identifier=event.channel_identifier,
        evt=event,
    )

    # check for known monitor calls and update accordingly
    update_status = channel.update_status
    if update_status is None:
        log.info(
            "Creating channel update state",
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            new_nonce=event.nonce,
            new_sender=event.ms_address,
        )

        channel.update_status = OnChainUpdateStatus(
            update_sender_address=event.ms_address, nonce=event.nonce)

        context.database.upsert_channel(channel)
    else:
        # nonce not bigger, should never happen as it is checked in the contract
        if event.nonce < update_status.nonce:
            log.error(
                "MSC NewBalanceProof nonce smaller than the known one, ignoring.",
                know_nonce=update_status.nonce,
                received_nonce=event.nonce,
            )
            metrics.get_metrics_for_label(
                metrics.ERRORS_LOGGED, metrics.ErrorCategory.PROTOCOL).inc()
            return

        log.info(
            "Updating channel update state",
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            new_nonce=event.nonce,
            new_sender=event.ms_address,
        )
        # update channel status
        update_status.nonce = event.nonce
        update_status.update_sender_address = event.ms_address

        context.database.upsert_channel(channel)

    # check if this was our update, if so schedule the call of
    # `claimReward` it will be checked there that our update was the latest one
    if event.ms_address == context.ms_state.address:
        assert channel.closing_block is not None, "closing_block not set"
        # Transactions go into the next mined block, so we could trigger one block
        # before the `claim` call is allowed to succeed to include it in the
        # first possible block.
        # Unfortunately, parity does the gas estimation on the current block
        # instead of the next one, so we have to wait for the first allowed
        # block to be finished to send the transaction successfully on parity.
        trigger_block = BlockNumber(channel.closing_block +
                                    channel.settle_timeout + 1)

        # trigger the claim reward action by an event
        triggered_event = ActionClaimRewardTriggeredEvent(
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            non_closing_participant=event.raiden_node_address,
        )

        log.info(
            "Received event for own update, triggering reward claim",
            token_network_address=event.token_network_address,
            identifier=channel.identifier,
            scheduled_event=triggered_event,
            trigger_block=trigger_block,
            closing_block=channel.closing_block,
            settle_timeout=channel.settle_timeout,
        )

        # Add scheduled event if it not exists yet
        # If the event is already scheduled (e.g. after a restart) the DB takes care that
        # it is only stored once
        context.database.upsert_scheduled_event(
            ScheduledEvent(trigger_block_number=trigger_block,
                           event=triggered_event))
Example #3
0
def monitor_new_balance_proof_event_handler(event: Event,
                                            context: Context) -> None:
    assert isinstance(event, ReceiveMonitoringNewBalanceProofEvent)
    channel = context.db.get_channel(event.token_network_address,
                                     event.channel_identifier)

    if channel is None:
        log.error(
            "Channel not in database",
            token_network_address=event.token_network_address,
            identifier=event.channel_identifier,
        )
        return

    log.info(
        "Received MSC NewBalanceProof event",
        token_network_address=event.token_network_address,
        identifier=event.channel_identifier,
        evt=event,
    )

    # check for known monitor calls and update accordingly
    update_status = channel.update_status
    if update_status is None:
        log.info(
            "Creating channel update state",
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            new_nonce=event.nonce,
            new_sender=event.ms_address,
        )

        channel.update_status = OnChainUpdateStatus(
            update_sender_address=event.ms_address, nonce=event.nonce)

        context.db.upsert_channel(channel)
    else:
        # nonce not bigger, should never happen as it is checked in the contract
        if event.nonce < update_status.nonce:
            log.error(
                "MSC NewBalanceProof nonce smaller than the known one, ignoring.",
                know_nonce=update_status.nonce,
                received_nonce=event.nonce,
            )
            return

        log.info(
            "Updating channel update state",
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            new_nonce=event.nonce,
            new_sender=event.ms_address,
        )
        # update channel status
        update_status.nonce = event.nonce
        update_status.update_sender_address = event.ms_address

        context.db.upsert_channel(channel)

    # check if this was our update, if so schedule the call
    # of `claimReward`
    # it will be checked there that our update was the latest one
    if event.ms_address == context.ms_state.address:
        assert channel.closing_block is not None, "closing_block not set"
        trigger_block = BlockNumber(channel.closing_block +
                                    channel.settle_timeout)

        # trigger the claim reward action by an event
        event = ActionClaimRewardTriggeredEvent(
            token_network_address=channel.token_network_address,
            channel_identifier=channel.identifier,
            non_closing_participant=event.raiden_node_address,
        )

        # Add scheduled event if it not exists yet
        # If the event is already scheduled (e.g. after a restart) the DB takes care that
        # it is only stored once
        context.db.upsert_scheduled_event(
            ScheduledEvent(trigger_block_number=trigger_block,
                           event=cast(Event, event)))