public CompletableFuture<Account> confirmReservedUsernameHash(final Account account, final byte[] reservedUsernameHash, @Nullable final byte[] encryptedUsername) {
    if (account.getUsernameHash().map(currentUsernameHash -> Arrays.equals(currentUsernameHash, reservedUsernameHash)).orElse(false)) {
      // the client likely already succeeded and is retrying
      return CompletableFuture.completedFuture(account);
    }

    if (!account.getReservedUsernameHash().map(oldHash -> Arrays.equals(oldHash, reservedUsernameHash)).orElse(false)) {
      // no such reservation existed, either there was no previous call to reserveUsername
      // or the reservation changed
      return CompletableFuture.failedFuture(new UsernameReservationNotFoundException());
    }

    return redisDeleteAsync(account)
        .thenCompose(ignored -> updateWithRetriesAsync(
            account,
            a -> true,
            a -> accounts.confirmUsernameHash(a, reservedUsernameHash, encryptedUsername),
            () -> accounts.getByAccountIdentifierAsync(account.getUuid()).thenApply(Optional::orElseThrow),
            AccountChangeValidator.USERNAME_CHANGE_VALIDATOR,
            MAX_UPDATE_ATTEMPTS
        ))
        .whenComplete((updatedAccount, throwable) -> {
          if (throwable == null) {
            // Make a best effort to clear any stale data that may have been cached while this operation was in progress
            redisDeleteAsync(updatedAccount);
          }
        });
  }
@Test
  void testConfirmReservedLapsed() {
    final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
    // hash was reserved, but the reservation lapsed and another account took it
    setReservationHash(account, USERNAME_HASH_1);
    when(accounts.confirmUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1))
        .thenReturn(CompletableFuture.failedFuture(new UsernameHashNotAvailableException()));
    CompletableFutureTestUtil.assertFailsWithCause(UsernameHashNotAvailableException.class,
        accountsManager.confirmReservedUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1));
    assertTrue(account.getUsernameHash().isEmpty());
  }