use of tech.pegasys.teku.pow.exception.Eth1RequestException in project teku by ConsenSys.
the class DepositsFetcherTest method shouldReduceBatchSizeWhenRequestIsRejected.
@Test
void shouldReduceBatchSizeWhenRequestIsRejected() {
final BigInteger fromBlockNumber = BigInteger.ZERO;
final BigInteger toBlockNumber = BigInteger.valueOf(MAX_BLOCK_RANGE + 100);
final SafeFuture<List<DepositContract.DepositEventEventResponse>> request1Response = new SafeFuture<>();
final SafeFuture<List<DepositContract.DepositEventEventResponse>> request2Response = new SafeFuture<>();
final SafeFuture<List<DepositContract.DepositEventEventResponse>> request3Response = new SafeFuture<>();
when(depositEventsAccessor.depositEventInRange(any(), any())).thenReturn(request1Response).thenReturn(request2Response).thenReturn(request3Response);
final SafeFuture<Void> result = depositFetcher.fetchDepositsInRange(fromBlockNumber, toBlockNumber);
assertThat(result).isNotDone();
// First tries to request a full size batch
verify(depositEventsAccessor).depositEventInRange(refEq(DefaultBlockParameter.valueOf(fromBlockNumber)), refEq(DefaultBlockParameter.valueOf(BigInteger.valueOf(MAX_BLOCK_RANGE))));
verifyNoMoreInteractions(depositEventsAccessor);
// But there are too many results
final Eth1RequestException err = new Eth1RequestException();
err.addSuppressed(new RejectedRequestException(-32005, "Nah mate"));
request1Response.completeExceptionally(err);
// So it halves the batch size and retries
asyncRunner.executeQueuedActions();
final BigInteger endSuccessfulRange = fromBlockNumber.add(BigInteger.valueOf(MAX_BLOCK_RANGE / 2));
verify(depositEventsAccessor).depositEventInRange(refEq(DefaultBlockParameter.valueOf(fromBlockNumber)), refEq(DefaultBlockParameter.valueOf(endSuccessfulRange)));
verifyNoMoreInteractions(depositEventsAccessor);
// And that works
request2Response.complete(emptyList());
// So it increases the batch size by 10% to avoid getting stuck with a very small batch size
asyncRunner.executeQueuedActions();
verify(depositEventsAccessor).depositEventInRange(refEq(DefaultBlockParameter.valueOf(endSuccessfulRange.add(BigInteger.ONE))), refEq(DefaultBlockParameter.valueOf(toBlockNumber)));
verifyNoMoreInteractions(depositEventsAccessor);
}
use of tech.pegasys.teku.pow.exception.Eth1RequestException in project teku by ConsenSys.
the class DepositFetcher method sendNextBatchRequest.
private SafeFuture<Void> sendNextBatchRequest(final DepositFetchState fetchState) {
final BigInteger nextBatchEnd = fetchState.getNextBatchEnd();
LOG.debug("Requesting deposits between {} and {}. Batch size: {}", fetchState.nextBatchStart, nextBatchEnd, fetchState.batchSize);
return processDepositsInBatch(fetchState.nextBatchStart, nextBatchEnd).exceptionallyCompose((err) -> {
LOG.debug("Failed to request deposit events for block numbers in the range ({}, {}). Retrying.", fetchState.nextBatchStart, nextBatchEnd, err);
final Throwable rootCause = Throwables.getRootCause(err);
if (rootCause instanceof InvalidDepositEventsException) {
STATUS_LOG.eth1DepositEventsFailure(rootCause);
} else if (rootCause instanceof Eth1RequestException && ((Eth1RequestException) rootCause).containsExceptionSolvableWithSmallerRange()) {
STATUS_LOG.eth1FetchDepositsRequiresSmallerRange(fetchState.batchSize);
fetchState.reduceBatchSize();
}
return asyncRunner.runAfterDelay(() -> sendNextBatchRequest(fetchState), Constants.ETH1_DEPOSIT_REQUEST_RETRY_TIMEOUT);
}).thenCompose(__ -> {
fetchState.moveToNextBatch();
LOG.trace("Batch request completed. Done? {}", fetchState.isDone());
if (fetchState.isDone()) {
return SafeFuture.COMPLETE;
} else {
return sendNextBatchRequest(fetchState);
}
});
}
Aggregations