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

Fix ValidatorApiHandlerTest for new BlobSidecar #7744

Merged
merged 4 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -50,6 +50,7 @@
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import tech.pegasys.teku.api.ChainDataProvider;
import tech.pegasys.teku.api.NodeDataProvider;
Expand All @@ -66,6 +67,8 @@
import tech.pegasys.teku.infrastructure.ssz.SszList;
import tech.pegasys.teku.infrastructure.ssz.SszMutableList;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.kzg.KZGCommitment;
import tech.pegasys.teku.kzg.KZGProof;
import tech.pegasys.teku.networking.eth2.gossip.BlobSidecarGossipChannel;
import tech.pegasys.teku.networking.eth2.gossip.BlockGossipChannel;
import tech.pegasys.teku.networking.eth2.gossip.subnets.AttestationTopicSubscriber;
Expand All @@ -76,10 +79,13 @@
import tech.pegasys.teku.spec.config.SpecConfig;
import tech.pegasys.teku.spec.config.SpecConfigAltair;
import tech.pegasys.teku.spec.datastructures.attestation.ValidatableAttestation;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.Blob;
import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar;
import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.BlockContainer;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState;
import tech.pegasys.teku.spec.datastructures.blocks.SignedBlockContainer;
import tech.pegasys.teku.spec.datastructures.blocks.versions.deneb.SignedBlockContents;
import tech.pegasys.teku.spec.datastructures.builder.SignedValidatorRegistration;
import tech.pegasys.teku.spec.datastructures.builder.ValidatorRegistration;
Expand All @@ -93,8 +99,11 @@
import tech.pegasys.teku.spec.datastructures.state.CheckpointState;
import tech.pegasys.teku.spec.datastructures.state.Validator;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.datastructures.type.SszKZGProof;
import tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult;
import tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;
import tech.pegasys.teku.spec.util.DataStructureUtil;
import tech.pegasys.teku.statetransition.attestation.AggregatingAttestationPool;
import tech.pegasys.teku.statetransition.attestation.AttestationManager;
Expand Down Expand Up @@ -152,6 +161,14 @@ class ValidatorApiHandlerTest {
private final SyncCommitteeSubscriptionManager syncCommitteeSubscriptionManager =
mock(SyncCommitteeSubscriptionManager.class);

@SuppressWarnings("unchecked")
private final ArgumentCaptor<List<BlobSidecar>> blobSidecarsCaptor1 =
ArgumentCaptor.forClass(List.class);

@SuppressWarnings("unchecked")
private final ArgumentCaptor<List<BlobSidecar>> blobSidecarsCaptor2 =
ArgumentCaptor.forClass(List.class);

private Spec spec;
private UInt64 epochStartSlot;
private UInt64 previousEpochStartSlot;
Expand Down Expand Up @@ -831,15 +848,21 @@ public void sendSignedBlock_shouldConvertBlockContentsSuccessfulResult() {
final SignedBlockContents blockContents =
dataStructureUtil.randomSignedBlockContents(UInt64.valueOf(5));
final SignedBeaconBlock block = blockContents.getSignedBlock();
final List<BlobSidecarSummary> expectedBlobSidecars =
BlobSidecarSummary.fromSignedBlockContents(blockContents);

when(blockImportChannel.importBlock(block, NOT_REQUIRED))
.thenReturn(prepareBlockImportResult(BlockImportResult.successful(block)));
final SafeFuture<SendSignedBlockResult> result =
validatorApiHandler.sendSignedBlock(blockContents, NOT_REQUIRED);

// TODO: fix assertion for blob sidecars
verify(blobSidecarGossipChannel).publishBlobSidecars(List.of());
verify(blobSidecarPool).onCompletedBlockAndBlobSidecars(block, List.of());
verify(blobSidecarGossipChannel).publishBlobSidecars(blobSidecarsCaptor1.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor1.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blobSidecarPool)
.onCompletedBlockAndBlobSidecars(eq(block), blobSidecarsCaptor2.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor2.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blockGossipChannel).publishBlock(block);
verify(blockImportChannel).importBlock(block, NOT_REQUIRED);
assertThat(result).isCompletedWithValue(SendSignedBlockResult.success(block.getRoot()));
Expand All @@ -851,15 +874,21 @@ public void sendSignedBlock_shouldConvertBlockContentsFailedResult() {
final SignedBlockContents blockContents =
dataStructureUtil.randomSignedBlockContents(UInt64.valueOf(5));
final SignedBeaconBlock block = blockContents.getSignedBlock();
final List<BlobSidecarSummary> expectedBlobSidecars =
BlobSidecarSummary.fromSignedBlockContents(blockContents);

when(blockImportChannel.importBlock(block, NOT_REQUIRED))
.thenReturn(prepareBlockImportResult(BlockImportResult.FAILED_INVALID_ANCESTRY));
final SafeFuture<SendSignedBlockResult> result =
validatorApiHandler.sendSignedBlock(blockContents, NOT_REQUIRED);

// TODO: fix assertion for blob sidecars
verify(blobSidecarGossipChannel).publishBlobSidecars(List.of());
verify(blobSidecarPool).onCompletedBlockAndBlobSidecars(block, List.of());
verify(blobSidecarGossipChannel).publishBlobSidecars(blobSidecarsCaptor1.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor1.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blobSidecarPool)
.onCompletedBlockAndBlobSidecars(eq(block), blobSidecarsCaptor2.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor2.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blockGossipChannel).publishBlock(block);
verify(blockImportChannel).importBlock(block, NOT_REQUIRED);
assertThat(result)
Expand All @@ -873,22 +902,28 @@ public void sendSignedBlockForDeneb_shouldConvertBlockContentsKnownBlockResult()
final SignedBlockContents blockContents =
dataStructureUtil.randomSignedBlockContents(UInt64.valueOf(5));
final SignedBeaconBlock block = blockContents.getSignedBlock();
final List<BlobSidecarSummary> expectedBlobSidecars =
BlobSidecarSummary.fromSignedBlockContents(blockContents);

when(blockImportChannel.importBlock(block, NOT_REQUIRED))
.thenReturn(prepareBlockImportResult(BlockImportResult.knownBlock(block, false)));
final SafeFuture<SendSignedBlockResult> result =
validatorApiHandler.sendSignedBlock(blockContents, NOT_REQUIRED);

// TODO: fix assertion for blob sidecars
verify(blobSidecarGossipChannel).publishBlobSidecars(List.of());
verify(blobSidecarPool).onCompletedBlockAndBlobSidecars(block, List.of());
verify(blobSidecarGossipChannel).publishBlobSidecars(blobSidecarsCaptor1.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor1.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blobSidecarPool)
.onCompletedBlockAndBlobSidecars(eq(block), blobSidecarsCaptor2.capture());
assertThat(BlobSidecarSummary.fromBlobSidecars(blobSidecarsCaptor2.getValue()))
.isEqualTo(expectedBlobSidecars);
verify(blockGossipChannel).publishBlock(block);
verify(blockImportChannel).importBlock(block, NOT_REQUIRED);
assertThat(result).isCompletedWithValue(SendSignedBlockResult.success(block.getRoot()));
}

@Test
public void sendSignedBlock_shoulNotGossipAndImportBlobsWhenBlobsDoNotExist() {
public void sendSignedBlock_shouldGossipAndImportEmptyBlobSidecarsWhenBlobsDoNotExist() {
setupDeneb();
final SignedBeaconBlock block = dataStructureUtil.randomSignedBeaconBlock(5);

Expand All @@ -898,7 +933,6 @@ public void sendSignedBlock_shoulNotGossipAndImportBlobsWhenBlobsDoNotExist() {
validatorApiHandler.sendSignedBlock(block, NOT_REQUIRED);
safeJoin(result);

// TODO: fix assertion for blob sidecars (there should be no interactions)
verify(blobSidecarPool).onCompletedBlockAndBlobSidecars(block, List.of());
verify(blobSidecarGossipChannel).publishBlobSidecars(List.of());
verify(blockGossipChannel).publishBlock(block);
Expand Down Expand Up @@ -1233,6 +1267,30 @@ private void setupDeneb() {
syncCommitteeMessagePool,
syncCommitteeContributionPool,
syncCommitteeSubscriptionManager);

// BlobSidecar builder
doAnswer(
invocation -> {
final SignedBlockContainer blockContainer = invocation.getArgument(0);
final MiscHelpersDeneb miscHelpersDeneb =
MiscHelpersDeneb.required(spec.forMilestone(SpecMilestone.DENEB).miscHelpers());
if (blockContainer.getBlobs().isEmpty()) {
return List.of();
}
final SszList<Blob> blobs = blockContainer.getBlobs().orElseThrow();
final SszList<SszKZGProof> proofs = blockContainer.getKzgProofs().orElseThrow();
return IntStream.range(0, blobs.size())
.mapToObj(
index ->
miscHelpersDeneb.constructBlobSidecar(
blockContainer.getSignedBlock(),
UInt64.valueOf(index),
blobs.get(index),
proofs.get(index)))
.toList();
})
.when(blockFactory)
.createBlobSidecars(any());
}

private SafeFuture<BlockImportAndBroadcastValidationResults> prepareBlockImportResult(
Expand All @@ -1241,4 +1299,47 @@ private SafeFuture<BlockImportAndBroadcastValidationResults> prepareBlockImportR
new BlockImportAndBroadcastValidationResults(
SafeFuture.completedFuture(blockImportResult)));
}

private record BlobSidecarSummary(
Blob blob, KZGProof kzgProof, KZGCommitment commitment, Bytes32 blockRoot) {
static List<BlobSidecarSummary> fromSignedBlockContents(
final SignedBlockContents signedBlockContents) {
final List<Blob> blobs = signedBlockContents.getBlobs().orElseThrow().asList();
final List<KZGProof> proofs =
signedBlockContents.getKzgProofs().orElseThrow().stream()
.map(SszKZGProof::getKZGProof)
.toList();
final List<KZGCommitment> commitments =
signedBlockContents
.getSignedBlock()
.getMessage()
.getBody()
.getOptionalBlobKzgCommitments()
.orElseThrow()
.stream()
.map(SszKZGCommitment::getKZGCommitment)
.toList();
return IntStream.range(0, blobs.size())
.mapToObj(
index ->
new BlobSidecarSummary(
blobs.get(index),
proofs.get(index),
commitments.get(index),
signedBlockContents.getRoot()))
.toList();
}

static List<BlobSidecarSummary> fromBlobSidecars(final List<BlobSidecar> blobSidecars) {
return blobSidecars.stream()
.map(
blobSidecar ->
new BlobSidecarSummary(
blobSidecar.getBlob(),
blobSidecar.getKZGProof(),
blobSidecar.getKZGCommitment(),
blobSidecar.getBlockRoot()))
.toList();
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2311,9 +2311,15 @@ public SignedBlockContents randomSignedBlockContents() {

public SignedBlockContents randomSignedBlockContents(final UInt64 slot) {
final SignedBeaconBlock signedBeaconBlock = randomSignedBeaconBlock(slot);
final int randomNumberOfBlobs = randomNumberOfBlobsPerBlock();
final List<Blob> blobs = randomBlobs(randomNumberOfBlobs, slot);
final List<KZGProof> kzgProofs = randomKZGProofs(randomNumberOfBlobs);
final int numberOfBlobs =
signedBeaconBlock
.getMessage()
.getBody()
.getOptionalBlobKzgCommitments()
.orElseThrow()
.size();
final List<Blob> blobs = randomBlobs(numberOfBlobs, slot);
final List<KZGProof> kzgProofs = randomKZGProofs(numberOfBlobs);
return getDenebSchemaDefinitions(slot)
.getSignedBlockContentsSchema()
.create(signedBeaconBlock, kzgProofs, blobs);
Expand All @@ -2338,9 +2344,10 @@ public BlockContents randomBlockContents() {

public BlockContents randomBlockContents(final UInt64 slot) {
final BeaconBlock beaconBlock = randomBeaconBlock(slot);
final int randomNumberOfBlobs = randomNumberOfBlobsPerBlock();
final List<Blob> blobs = randomBlobs(randomNumberOfBlobs, slot);
final List<KZGProof> kzgProofs = randomKZGProofs(randomNumberOfBlobs);
final int numberOfBlobs =
beaconBlock.getBody().getOptionalBlobKzgCommitments().orElseThrow().size();
final List<Blob> blobs = randomBlobs(numberOfBlobs, slot);
final List<KZGProof> kzgProofs = randomKZGProofs(numberOfBlobs);
return getDenebSchemaDefinitions(slot)
.getBlockContentsSchema()
.create(beaconBlock, kzgProofs, blobs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import tech.pegasys.teku.spec.schemas.SchemaDefinitions;
import tech.pegasys.teku.spec.util.DataStructureUtil;

/** Use {@link #serializeSszObjectToJsonWithDataWrapper(SszData)} for serializing object to JSON */
public class AbstractTypeDefRequestTestBase {

protected static final String JSON_CONTENT_TYPE = "application/json; charset=utf-8";
Expand Down

Large diffs are not rendered by default.

Loading