Skip to content

Commit 196c4c1

Browse files
Handle errors on reporting tasks (#7062)
1 parent 67df8e3 commit 196c4c1

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

beacon/validator/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies {
3737
testImplementation testFixtures(project(':ethereum:networks'))
3838
testImplementation testFixtures(project(':storage'))
3939
testImplementation testFixtures(project(':infrastructure:async'))
40+
testImplementation testFixtures(project(':infrastructure:logging'))
4041
testImplementation testFixtures(project(':infrastructure:metrics'))
4142
testImplementation testFixtures(project(':infrastructure:time'))
4243

beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/performance/DefaultPerformanceTracker.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import java.util.concurrent.atomic.AtomicInteger;
3737
import java.util.concurrent.atomic.AtomicReference;
3838
import java.util.stream.Collectors;
39+
import org.apache.logging.log4j.LogManager;
40+
import org.apache.logging.log4j.Logger;
3941
import org.apache.tuweni.bytes.Bytes32;
4042
import tech.pegasys.teku.infrastructure.async.SafeFuture;
4143
import tech.pegasys.teku.infrastructure.logging.StatusLogger;
@@ -53,6 +55,7 @@
5355
import tech.pegasys.teku.validator.coordinator.ActiveValidatorTracker;
5456

5557
public class DefaultPerformanceTracker implements PerformanceTracker {
58+
private static final Logger LOG = LogManager.getLogger();
5659

5760
@VisibleForTesting
5861
final NavigableMap<UInt64, Set<SlotAndBlockRoot>> producedBlocksByEpoch =
@@ -136,7 +139,7 @@ public void onSlot(UInt64 slot) {
136139
reportingTasks.add(reportSyncCommitteePerformance(currentEpoch));
137140
}
138141

139-
SafeFuture.allOf(reportingTasks.toArray(SafeFuture[]::new)).join();
142+
SafeFuture.allOf(reportingTasks.toArray(SafeFuture[]::new)).handleException(LOG::error).join();
140143
}
141144

142145
private SafeFuture<?> reportBlockPerformance(final UInt64 currentEpoch) {

beacon/validator/src/test/java/tech/pegasys/teku/validator/coordinator/performance/DefaultPerformanceTrackerTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import static org.mockito.Mockito.mock;
2020
import static org.mockito.Mockito.never;
2121
import static org.mockito.Mockito.verify;
22+
import static org.mockito.Mockito.verifyNoInteractions;
2223
import static org.mockito.Mockito.when;
2324
import static tech.pegasys.teku.validator.coordinator.performance.DefaultPerformanceTracker.ATTESTATION_INCLUSION_RANGE;
2425

2526
import java.util.List;
2627
import org.junit.jupiter.api.BeforeEach;
2728
import org.junit.jupiter.api.Test;
29+
import tech.pegasys.infrastructure.logging.LogCaptor;
2830
import tech.pegasys.teku.bls.BLSKeyGenerator;
2931
import tech.pegasys.teku.bls.BLSKeyPair;
3032
import tech.pegasys.teku.bls.BLSTestUtil;
@@ -362,6 +364,41 @@ void shouldReportSyncCommitteePerformance() {
362364
verify(validatorPerformanceMetrics).updateSyncCommitteePerformance(performance);
363365
}
364366

367+
@Test
368+
void shouldHandleErrorsWhenReportTasksFail() {
369+
chainUpdater.updateBestBlock(chainUpdater.advanceChainUntil(1));
370+
final Attestation attestation = createAttestationForParentBlockOnSlot(1);
371+
final UInt64 slot = spec.computeStartSlotAtEpoch(ATTESTATION_INCLUSION_RANGE);
372+
373+
performanceTracker.saveProducedAttestation(attestation);
374+
when(validatorTracker.getNumberOfValidatorsForEpoch(any())).thenThrow(new RuntimeException());
375+
376+
try (LogCaptor logCaptor = LogCaptor.forClass(DefaultPerformanceTracker.class)) {
377+
performanceTracker.onSlot(slot);
378+
379+
// No attestation performance report on status logger because task failed
380+
verifyNoInteractions(log);
381+
assertThat(logCaptor.getErrorLogs()).hasSize(1);
382+
}
383+
}
384+
385+
/**
386+
* Creates an attestation voting for block on the slot provided. The attestation will be included
387+
* in block slot + 1.
388+
*
389+
* @param slot the slot of the block being attested
390+
* @return the created attestation
391+
*/
392+
private Attestation createAttestationForParentBlockOnSlot(int slot) {
393+
Attestation attestationForBlock1 = createAttestation(slot + 1, slot);
394+
ChainBuilder.BlockOptions block2Options = ChainBuilder.BlockOptions.create();
395+
block2Options.addAttestation(attestationForBlock1);
396+
SignedBlockAndState latestBlockAndState = chainBuilder.generateBlockAtSlot(2, block2Options);
397+
chainUpdater.saveBlock(latestBlockAndState);
398+
chainUpdater.updateBestBlock(latestBlockAndState);
399+
return attestationForBlock1;
400+
}
401+
365402
private Attestation createAttestation(
366403
ChainBuilder chainBuilder, int validForBlockAtSlot, int vouchingForBlockAtSlot) {
367404
return chainBuilder

0 commit comments

Comments
 (0)