Determine whether a lock has expired.

    The lock has expired if both:

        - The secret was not registered on-chain in time.
        - The current block exceeds lock's expiration + confirmation blocks.

def is_lock_expired(
        end_state: NettingChannelEndState,
        lock: LockType,
        block_number: BlockNumber,
        lock_expiration_threshold: BlockNumber,
) -> SuccessOrError:
    """ Determine whether a lock has expired.

    The lock has expired if both:

        - The secret was not registered on-chain in time.
        - The current block exceeds lock's expiration + confirmation blocks.
    """

    secret_registered_on_chain = lock.secrethash in end_state.secrethashes_to_onchain_unlockedlocks
    if secret_registered_on_chain:
        return (False, 'lock has been unlocked on-chain')

    if block_number < lock_expiration_threshold:
        msg = (
            f'current block number ({block_number}) is not larger than '
            f'lock.expiration + confirmation blocks ({lock_expiration_threshold})'
        )
        return (False, msg)

    return (True, None)