Search in sources :

Example 1 with Eth1RequestException

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);
}
Also used : Eth1RequestException(tech.pegasys.teku.pow.exception.Eth1RequestException) RejectedRequestException(tech.pegasys.teku.pow.exception.RejectedRequestException) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) BigInteger(java.math.BigInteger) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) DepositContract(tech.pegasys.teku.pow.contract.DepositContract) Test(org.junit.jupiter.api.Test)

Example 2 with Eth1RequestException

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);
        }
    });
}
Also used : EthBlock(org.web3j.protocol.core.methods.response.EthBlock) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) SafeFuture(tech.pegasys.teku.infrastructure.async.SafeFuture) Eth1RequestException(tech.pegasys.teku.pow.exception.Eth1RequestException) DepositEventEventResponse(tech.pegasys.teku.pow.contract.DepositContract.DepositEventEventResponse) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Map(java.util.Map) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) BigInteger(java.math.BigInteger) Constants(tech.pegasys.teku.spec.config.Constants) DepositsFromBlockEvent(tech.pegasys.teku.ethereum.pow.api.DepositsFromBlockEvent) Bytes32(org.apache.tuweni.bytes.Bytes32) AsyncRunner(tech.pegasys.teku.infrastructure.async.AsyncRunner) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Throwables(com.google.common.base.Throwables) Set(java.util.Set) DefaultBlockParameter(org.web3j.protocol.core.DefaultBlockParameter) NavigableMap(java.util.NavigableMap) Objects(java.util.Objects) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) InvalidDepositEventsException(tech.pegasys.teku.ethereum.pow.api.InvalidDepositEventsException) Logger(org.apache.logging.log4j.Logger) TreeMap(java.util.TreeMap) STATUS_LOG(tech.pegasys.teku.infrastructure.logging.StatusLogger.STATUS_LOG) Comparator(java.util.Comparator) DepositContract(tech.pegasys.teku.pow.contract.DepositContract) LogManager(org.apache.logging.log4j.LogManager) Eth1EventsChannel(tech.pegasys.teku.pow.api.Eth1EventsChannel) Eth1RequestException(tech.pegasys.teku.pow.exception.Eth1RequestException) BigInteger(java.math.BigInteger) InvalidDepositEventsException(tech.pegasys.teku.ethereum.pow.api.InvalidDepositEventsException)

Aggregations

BigInteger (java.math.BigInteger)2 List (java.util.List)2 SafeFuture (tech.pegasys.teku.infrastructure.async.SafeFuture)2 DepositContract (tech.pegasys.teku.pow.contract.DepositContract)2 Eth1RequestException (tech.pegasys.teku.pow.exception.Eth1RequestException)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Throwables (com.google.common.base.Throwables)1 Collections.emptyList (java.util.Collections.emptyList)1 Comparator (java.util.Comparator)1 Map (java.util.Map)1 NavigableMap (java.util.NavigableMap)1 Objects (java.util.Objects)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 Collectors.groupingBy (java.util.stream.Collectors.groupingBy)1 Collectors.toList (java.util.stream.Collectors.toList)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 Bytes32 (org.apache.tuweni.bytes.Bytes32)1