Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PART 2 - GET/Attestation Pool API - Retrieve attestations and metadata #8437

Merged
merged 3 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ public DataProvider build() {
isLivenessTrackingEnabled,
activeValidatorChannel,
proposersDataManager,
forkChoiceNotifier);
forkChoiceNotifier,
spec);
final ChainDataProvider chainDataProvider =
new ChainDataProvider(spec, recentChainData, combinedChainDataClient, rewardCalculator);
final SyncDataProvider syncDataProvider =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import static tech.pegasys.teku.statetransition.validatorcache.ActiveValidatorCache.TRACKED_EPOCHS;

import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -26,7 +27,9 @@
import tech.pegasys.teku.api.migrated.ValidatorLivenessAtEpoch;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.datastructures.attestation.ProcessedAttestationListener;
import tech.pegasys.teku.spec.datastructures.metadata.ObjectAndMetaData;
import tech.pegasys.teku.spec.datastructures.operations.Attestation;
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing;
Expand Down Expand Up @@ -63,6 +66,7 @@ public class NodeDataProvider {
private final boolean isLivenessTrackingEnabled;
private final ProposersDataManager proposersDataManager;
private final ForkChoiceNotifier forkChoiceNotifier;
private final Spec spec;

public NodeDataProvider(
final AggregatingAttestationPool attestationPool,
Expand All @@ -76,7 +80,8 @@ public NodeDataProvider(
final boolean isLivenessTrackingEnabled,
final ActiveValidatorChannel activeValidatorChannel,
final ProposersDataManager proposersDataManager,
final ForkChoiceNotifier forkChoiceNotifier) {
final ForkChoiceNotifier forkChoiceNotifier,
final Spec spec) {
this.attestationPool = attestationPool;
this.attesterSlashingPool = attesterSlashingsPool;
this.proposerSlashingPool = proposerSlashingPool;
Expand All @@ -89,13 +94,30 @@ public NodeDataProvider(
this.isLivenessTrackingEnabled = isLivenessTrackingEnabled;
this.proposersDataManager = proposersDataManager;
this.forkChoiceNotifier = forkChoiceNotifier;
this.spec = spec;
}

public List<Attestation> getAttestations(
final Optional<UInt64> maybeSlot, final Optional<UInt64> maybeCommitteeIndex) {
return attestationPool.getAttestations(maybeSlot, maybeCommitteeIndex);
}

public ObjectAndMetaData<List<Attestation>> getAttestationsAndMetaData(
final Optional<UInt64> maybeSlot, final Optional<UInt64> maybeCommitteeIndex) {
return lookupMetaData(
attestationPool.getAttestations(maybeSlot, maybeCommitteeIndex), maybeSlot);
}

private ObjectAndMetaData<List<Attestation>> lookupMetaData(
final List<Attestation> attestations, final Optional<UInt64> maybeSlot) {
Preconditions.checkArgument(
!attestations.isEmpty() || maybeSlot.isPresent(),
"Unable to determine spec version. No slot parameter provided and no attestations found");
mehdi-aouadi marked this conversation as resolved.
Show resolved Hide resolved
final UInt64 slot = maybeSlot.orElse(attestations.get(0).getData().getSlot());
return new ObjectAndMetaData<>(
attestations, spec.atSlot(slot).getMilestone(), false, false, false);
}

public List<AttesterSlashing> getAttesterSlashings() {
return new ArrayList<>(attesterSlashingPool.getAll());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,24 @@
package tech.pegasys.teku.api;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.SpecVersion;
import tech.pegasys.teku.spec.TestSpecFactory;
import tech.pegasys.teku.spec.datastructures.operations.AttesterSlashing;
import tech.pegasys.teku.spec.datastructures.operations.ProposerSlashing;
Expand Down Expand Up @@ -82,7 +89,8 @@ public void setup() {
false,
validatorChannel,
proposersDataManager,
forkChoiceNotifier);
forkChoiceNotifier,
spec);
}

@Test
Expand Down Expand Up @@ -113,4 +121,74 @@ void blsToExecutionChanges_ReturnsListOfErrors() throws ExecutionException, Inte
assertThat(future.get())
.isEqualTo(List.of(new SubmitDataError(UInt64.ONE, "Computer says no")));
}

@Test
void attestationsMetaDataLookUp_ThrowsWhenNoSlotAndNoAttestations() {
when(attestationPool.getAttestations(any(), any())).thenReturn(Collections.emptyList());
assertThatThrownBy(
() -> provider.getAttestationsAndMetaData(Optional.empty(), Optional.empty()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(
"Unable to determine spec version. No slot parameter provided and no attestations found");
}

@Test
void attestationsMetaDataLookUp_UseFirstAttestationSlot_WhenSlotParamNotProvided() {
final Spec specMock = mock(Spec.class);
final SpecVersion specVersionMock = mock(SpecVersion.class);
final SpecMilestone specMilestone = mock(SpecMilestone.class);
when(specVersionMock.getMilestone()).thenReturn(specMilestone);
when(specMock.atSlot(any())).thenReturn(specVersionMock);
provider =
new NodeDataProvider(
attestationPool,
attesterSlashingPool,
proposerSlashingPool,
voluntaryExitPool,
blsToExecutionChangePool,
syncCommitteeContributionPool,
blockBlobSidecarsTrackersPool,
attestationManager,
false,
validatorChannel,
proposersDataManager,
forkChoiceNotifier,
specMock);
when(attestationPool.getAttestations(any(), any()))
.thenReturn(
List.of(
dataStructureUtil.randomAttestation(5), dataStructureUtil.randomAttestation(10)));
provider.getAttestationsAndMetaData(Optional.empty(), Optional.empty());
verify(specMock).atSlot(eq(UInt64.valueOf(5)));
}

@Test
void attestationsMetaDataLookUp_UseSlot_WhenSlotParamNotProvided() {
final Spec specMock = mock(Spec.class);
final SpecVersion specVersionMock = mock(SpecVersion.class);
final SpecMilestone specMilestone = mock(SpecMilestone.class);
when(specVersionMock.getMilestone()).thenReturn(specMilestone);
when(specMock.atSlot(any())).thenReturn(specVersionMock);
provider =
new NodeDataProvider(
attestationPool,
attesterSlashingPool,
proposerSlashingPool,
voluntaryExitPool,
blsToExecutionChangePool,
syncCommitteeContributionPool,
blockBlobSidecarsTrackersPool,
attestationManager,
false,
validatorChannel,
proposersDataManager,
forkChoiceNotifier,
specMock);
when(attestationPool.getAttestations(any(), any()))
.thenReturn(
List.of(
dataStructureUtil.randomAttestation(5), dataStructureUtil.randomAttestation(10)));
provider.getAttestationsAndMetaData(Optional.of(UInt64.valueOf(8)), Optional.empty());
verify(specMock).atSlot(eq(UInt64.valueOf(8)));
}
}