def handle_block(
        initiator_state: InitiatorTransferState,
        state_change: Block,
        channel_state: NettingChannelState,
        pseudo_random_generator: random.Random,
) -> TransitionResult[InitiatorTransferState]:
    """ Checks if the lock has expired, and if it has sends a remove expired
    lock and emits the failing events.
    """
    secrethash = initiator_state.transfer.lock.secrethash
    locked_lock = channel_state.our_state.secrethashes_to_lockedlocks.get(secrethash)

    if not locked_lock:
        if channel_state.partner_state.secrethashes_to_lockedlocks.get(secrethash):
            return TransitionResult(initiator_state, list())
        else:
            # if lock is not in our or our partner's locked locks then the
            # task can go
            return TransitionResult(None, list())

    lock_expiration_threshold = BlockNumber(
        locked_lock.expiration + DEFAULT_WAIT_BEFORE_LOCK_REMOVAL,
    )
    lock_has_expired, _ = channel.is_lock_expired(
        end_state=channel_state.our_state,
        lock=locked_lock,
        block_number=state_change.block_number,
        lock_expiration_threshold=lock_expiration_threshold,
    )

    events: List[Event] = list()

    if lock_has_expired:
        is_channel_open = channel.get_status(channel_state) == CHANNEL_STATE_OPENED
        if is_channel_open:
            expired_lock_events = channel.events_for_expired_lock(
                channel_state=channel_state,
                locked_lock=locked_lock,
                pseudo_random_generator=pseudo_random_generator,
            )
            events.extend(expired_lock_events)

        if initiator_state.received_secret_request:
            reason = 'bad secret request message from target'
        else:
            reason = 'lock expired'

        transfer_description = initiator_state.transfer_description
        payment_identifier = transfer_description.payment_identifier
        # TODO: When we introduce multiple transfers per payment this needs to be
        #       reconsidered. As we would want to try other routes once a route
        #       has failed, and a transfer failing does not mean the entire payment
        #       would have to fail.
        #       Related issue: https://github.com/raiden-network/raiden/issues/2329
        payment_failed = EventPaymentSentFailed(
            payment_network_identifier=transfer_description.payment_network_identifier,
            token_network_identifier=transfer_description.token_network_identifier,
            identifier=payment_identifier,
            target=transfer_description.target,
            reason=reason,
        )
        unlock_failed = EventUnlockFailed(
            identifier=payment_identifier,
            secrethash=initiator_state.transfer_description.secrethash,
            reason=reason,
        )

        lock_exists = channel.lock_exists_in_either_channel_side(
            channel_state=channel_state,
            secrethash=secrethash,
        )

        return TransitionResult(
            # If the lock is either in our state or partner state we keep the
            # task around to wait for the LockExpired messages to sync.
            # Check https://github.com/raiden-network/raiden/issues/3183
            initiator_state if lock_exists else None,
            events + [payment_failed, unlock_failed],
        )
    else:
        return TransitionResult(initiator_state, events)
def handle_block ( initiator_state : InitiatorTransferState , state_change : Block , channel_state : NettingChannelState , pseudo_random_generator : random . Random , ) -> TransitionResult [ InitiatorTransferState ] : secrethash = initiator_state . transfer . lock . secrethash locked_lock = channel_state . our_state . secrethashes_to_lockedlocks . get ( secrethash ) if not locked_lock : if channel_state . partner_state . secrethashes_to_lockedlocks . get ( secrethash ) : return TransitionResult ( initiator_state , list ( ) ) else : return TransitionResult ( None , list ( ) ) lock_expiration_threshold = BlockNumber ( locked_lock . expiration + DEFAULT_WAIT_BEFORE_LOCK_REMOVAL , ) lock_has_expired , _ = channel . is_lock_expired ( end_state = channel_state . our_state , lock = locked_lock , block_number = state_change . block_number , lock_expiration_threshold = lock_expiration_threshold , ) events : List [ Event ] = list ( ) if lock_has_expired : is_channel_open = channel . get_status ( channel_state ) == CHANNEL_STATE_OPENED if is_channel_open : expired_lock_events = channel . events_for_expired_lock ( channel_state = channel_state , locked_lock = locked_lock , pseudo_random_generator = pseudo_random_generator , ) events . extend ( expired_lock_events ) if initiator_state . received_secret_request : reason = 'bad secret request message from target' else : reason = 'lock expired' transfer_description = initiator_state . transfer_description payment_identifier = transfer_description . payment_identifier payment_failed = EventPaymentSentFailed ( payment_network_identifier = transfer_description . payment_network_identifier , token_network_identifier = transfer_description . token_network_identifier , identifier = payment_identifier , target = transfer_description . target , reason = reason , ) unlock_failed = EventUnlockFailed ( identifier = payment_identifier , secrethash = initiator_state . transfer_description . secrethash , reason = reason , ) lock_exists = channel . lock_exists_in_either_channel_side ( channel_state = channel_state , secrethash = secrethash , ) return TransitionResult ( initiator_state if lock_exists else None , events + [ payment_failed , unlock_failed ] , ) else : return TransitionResult ( initiator_state , events )
Checks if the lock has expired, and if it has sends a remove expired
    lock and emits the failing events.