Skip to content

Commit

Permalink
Add timing metrics to SlotBasedScheduledDuties
Browse files Browse the repository at this point in the history
  • Loading branch information
courtneyeh committed Oct 10, 2023
1 parent 3f1106a commit 079c04c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ private void scheduleValidatorsDuties(
validatorApiChannel,
forkProvider,
dependentRoot ->
new SlotBasedScheduledDuties<>(attestationDutyFactory, dependentRoot),
new SlotBasedScheduledDuties<>(
attestationDutyFactory, dependentRoot, metricsSystem),
validators,
validatorIndexProvider,
beaconCommitteeSubscriptions,
Expand All @@ -419,7 +420,8 @@ private void scheduleValidatorsDuties(
asyncRunner,
new BlockProductionDutyLoader(
validatorApiChannel,
dependentRoot -> new SlotBasedScheduledDuties<>(blockDutyFactory, dependentRoot),
dependentRoot ->
new SlotBasedScheduledDuties<>(blockDutyFactory, dependentRoot, metricsSystem),
validators,
validatorIndexProvider));
validatorTimingChannels.add(new BlockDutyScheduler(metricsSystem, blockDutyLoader, spec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.tuweni.bytes.Bytes32;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.exceptions.InvalidConfigurationException;
import tech.pegasys.teku.infrastructure.metrics.TekuMetricCategory;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.validator.client.Validator;

Expand All @@ -30,10 +34,32 @@ public class SlotBasedScheduledDuties<P extends Duty, A extends Duty> implements
private final DutyFactory<P, A> dutyFactory;
private final Bytes32 dependentRoot;

private final OperationTimer attestationProductionDutyTimer;
private final OperationTimer blockProductionDutyTimer;
private final OperationTimer attestationAggregationDutyTimer;

public SlotBasedScheduledDuties(
final DutyFactory<P, A> dutyFactory, final Bytes32 dependentRoot) {
final DutyFactory<P, A> dutyFactory,
final Bytes32 dependentRoot,
final MetricsSystem metricsSystem) {
this.dutyFactory = dutyFactory;
this.dependentRoot = dependentRoot;

this.attestationProductionDutyTimer =
metricsSystem.createTimer(
TekuMetricCategory.VALIDATOR,
"attestation_duty_timer",
"Timer recording the time taken to perform an attestation duty");
this.blockProductionDutyTimer =
metricsSystem.createTimer(
TekuMetricCategory.VALIDATOR,
"block_duty_timer",
"Timer recording the time taken to perform a block duty");
this.attestationAggregationDutyTimer =
metricsSystem.createTimer(
TekuMetricCategory.VALIDATOR,
"aggregation_duty_timer",
"Timer recording the time taken to perform an aggregation duty");
}

public Bytes32 getDependentRoot() {
Expand Down Expand Up @@ -84,11 +110,36 @@ private SafeFuture<DutyResult> performDutyForSlot(
final NavigableMap<UInt64, ? extends Duty> duties, final UInt64 slot) {
discardDutiesBeforeSlot(duties, slot);

final Duty duty = duties.remove(slot); // todo this is the duty!
final Duty duty = duties.remove(slot);
if (duty == null) {
return SafeFuture.completedFuture(DutyResult.NO_OP);
}
return duty.performDuty(); // todo bring into method and override to do metrics

final boolean metricsOn = true; // todo work out if metrics are turned on
return metricsOn ? performDutyWithMetrics(duty) : duty.performDuty();
}

private OperationTimer getMetricTimer(final DutyType type) {
if (type.equals(DutyType.ATTESTATION_AGGREGATION)) {
return attestationAggregationDutyTimer;
} else if (type.equals(DutyType.ATTESTATION_PRODUCTION)) {
return attestationProductionDutyTimer;
} else if (type.equals(DutyType.BLOCK_PRODUCTION)) {
return blockProductionDutyTimer;
} else {
throw new InvalidConfigurationException(type.getType() + " is an invalid duty type");
}
}

private SafeFuture<DutyResult> performDutyWithMetrics(final Duty duty) {
final OperationTimer timer = getMetricTimer(duty.getType());
final OperationTimer.TimingContext context = timer.startTimer();
return duty.performDuty()
.thenApply(
result -> {
context.stopTimer();
return result;
});
}

private void discardDutiesBeforeSlot(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,9 @@ private void createDutySchedulerWithRealDuties() {
new AttestationDutyLoader(
validatorApiChannel,
forkProvider,
dependentRoot -> new SlotBasedScheduledDuties<>(attestationDutyFactory, dependentRoot),
dependentRoot ->
new SlotBasedScheduledDuties<>(
attestationDutyFactory, dependentRoot, metricsSystem),
new OwnedValidators(Map.of(VALIDATOR1_KEY, validator1, VALIDATOR2_KEY, validator2)),
validatorIndexProvider,
beaconCommitteeSubscriptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,8 @@ private void createDutySchedulerWithRealDuties() {
new BlockProductionDutyLoader(
validatorApiChannel,
dependentRoot ->
new SlotBasedScheduledDuties<>(blockDutyFactory, dependentRoot),
new SlotBasedScheduledDuties<>(
blockDutyFactory, dependentRoot, metricsSystem),
new OwnedValidators(
Map.of(VALIDATOR1_KEY, validator1, VALIDATOR2_KEY, validator2)),
validatorIndexProvider)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.metrics.StubMetricsSystem;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.TestSpecFactory;
Expand All @@ -37,6 +38,7 @@ class SlotBasedScheduledDutiesTest {
private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec);
public static final UInt64 TWO = UInt64.valueOf(2);
private final Validator validator = mock(Validator.class);
final StubMetricsSystem metricsSystem = new StubMetricsSystem();

@SuppressWarnings("unchecked")
private final Function<ProductionDuty, String> productionDutyAdder = mock(Function.class);
Expand All @@ -48,7 +50,7 @@ class SlotBasedScheduledDutiesTest {
private final DutyFactory<ProductionDuty, AggregationDuty> dutyFactory = mock(DutyFactory.class);

private final SlotBasedScheduledDuties<ProductionDuty, AggregationDuty> duties =
new SlotBasedScheduledDuties<>(dutyFactory, Bytes32.fromHexString("0x838382"));
new SlotBasedScheduledDuties<>(dutyFactory, Bytes32.fromHexString("0x838382"), metricsSystem);

@Test
public void shouldDiscardMissedProductionDuties() {
Expand Down

0 comments on commit 079c04c

Please sign in to comment.