class NonceRefreshingTxRequester implements TxRequester {

  @Override
  public TxHash request(final AergoClient aergoClient, final Signer signer,
      final TxRequestFunction requestFunction) throws Exception {
    assertNotNull(aergoClient, "AergoClient must not null");
    assertNotNull(signer, "Signer must not null");
    assertNotNull(requestFunction, "RequestFunction must not null");
    logger.debug("Transaction try with signer: {}, requestFunction: {}", signer,
        requestFunction);

    TxHash txHash = null;
    Exception error = null;

    final long sleepInterval = tryCountAndInterval.getInterval().toMilliseconds();
    int count = tryCountAndInterval.getCount();
    while (0 <= count && null == txHash) {
      final long nonce = nonceProvider.incrementAndGetNonce(signer.getPrincipal());
      try {
        txHash = requestFunction.apply(signer, nonce);
      } catch (Exception e) {
        error = e;
        if (isNonceRelatedException(e)) {
          final CommitException commitException = (CommitException) e;
          logger.debug("Request failed with {}. Refresh it (try left: {})",
              commitException.getCommitStatus(), count);
          syncNonce(aergoClient, signer.getPrincipal());
        } else {
          throw e;
        }

        ThreadUtils.trySleep(sleepInterval);
        --count;
      }
    }

    if (null == txHash && null != error) {
      throw error;
    }

    return txHash;
  }

}