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

[Merge] add merge Beacon API support #4537

Merged
merged 22 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from 19 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 @@ -63,7 +63,7 @@
import tech.pegasys.teku.api.response.v2.beacon.GetBlockResponseV2;
import tech.pegasys.teku.api.schema.BeaconState;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.api.schema.altair.SignedBeaconBlockAltair;
import tech.pegasys.teku.api.schema.SignedBeaconBlock.SignedBeaconBlockAltair;
import tech.pegasys.teku.api.schema.altair.SignedContributionAndProof;
import tech.pegasys.teku.api.schema.interfaces.SignedBlock;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
Expand Down Expand Up @@ -417,16 +417,16 @@ public void waitForAttestationBeingGossiped(
final Optional<BeaconState> maybeState = fetchHeadState();
assertThat(maybeBlock).isPresent();
assertThat(maybeState).isPresent();
SignedBeaconBlock block = (SignedBeaconBlock) maybeBlock.get();
SignedBeaconBlock<?> block = (SignedBeaconBlock<?>) maybeBlock.get();
BeaconState state = maybeState.get();

// Check that the fetched block and state are in sync
assertThat(state.latest_block_header.parent_root)
.isEqualTo(block.getMessage().parent_root);
.isEqualTo(block.getMessage().parentRoot);

tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState internalBeaconState =
state.asInternalBeaconState(spec);
UInt64 proposerIndex = block.getMessage().proposer_index;
UInt64 proposerIndex = block.getMessage().proposerIndex;

Set<UInt64> attesterIndicesInAttestations =
block.getMessage().getBody().attestations.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,16 @@ public ArrayList<BeaconBlockAndState> importBlocksAtSlots(UInt64... slots) throw
return results;
}

public List<SignedBeaconBlock> createBlocksAtSlotsAndMapToApiResult(long... slots) {
public List<SignedBeaconBlock<?>> createBlocksAtSlotsAndMapToApiResult(long... slots) {
final UInt64[] unsignedSlots =
Arrays.stream(slots).mapToObj(UInt64::valueOf).toArray(UInt64[]::new);
return createBlocksAtSlotsAndMapToApiResult(unsignedSlots);
}

public List<SignedBeaconBlock> createBlocksAtSlotsAndMapToApiResult(UInt64... slots) {
public List<SignedBeaconBlock<?>> createBlocksAtSlotsAndMapToApiResult(UInt64... slots) {
return createBlocksAtSlots(slots).stream()
.map(SignedBlockAndState::getBlock)
.map(SignedBeaconBlock::new)
.map(SignedBeaconBlock::create)
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import okhttp3.Response;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.api.response.v1.beacon.GetBlockResponse;
import tech.pegasys.teku.api.schema.BLSSignature;
import tech.pegasys.teku.api.schema.BeaconBlock;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.beaconrestapi.AbstractDataBackedRestAPIIntegrationTest;
import tech.pegasys.teku.beaconrestapi.handlers.v1.beacon.GetBlock;
Expand All @@ -38,13 +36,9 @@ public void shouldGetBlock() throws IOException {

final GetBlockResponse body =
jsonProvider.jsonToObject(response.body().string(), GetBlockResponse.class);
final SignedBeaconBlock data = body.data;
final SignedBeaconBlock<?> data = body.data;
final SignedBlockAndState block = created.get(0);
assertThat(data)
.isEqualTo(
new SignedBeaconBlock(
new BeaconBlock(block.getBlock().getMessage()),
new BLSSignature(block.getBlock().getSignature())));
assertThat(data).isEqualTo(SignedBeaconBlock.create(block.getBlock()));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.Test;
import tech.pegasys.teku.api.response.v2.beacon.GetBlockResponseV2;
import tech.pegasys.teku.api.schema.BLSSignature;
import tech.pegasys.teku.api.schema.BeaconBlock;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.api.schema.SignedBeaconBlock.SignedBeaconBlockAltair;
import tech.pegasys.teku.api.schema.SignedBeaconBlock.SignedBeaconBlockPhase0;
import tech.pegasys.teku.api.schema.Version;
import tech.pegasys.teku.api.schema.altair.SignedBeaconBlockAltair;
import tech.pegasys.teku.api.schema.phase0.SignedBeaconBlockPhase0;
import tech.pegasys.teku.beaconrestapi.AbstractDataBackedRestAPIIntegrationTest;
import tech.pegasys.teku.beaconrestapi.handlers.v2.beacon.GetBlock;
import tech.pegasys.teku.spec.SpecMilestone;
Expand All @@ -48,11 +47,7 @@ public void shouldGetBlock() throws IOException {
assertThat(body.data).isInstanceOf(SignedBeaconBlockPhase0.class);
final SignedBeaconBlockPhase0 data = (SignedBeaconBlockPhase0) body.getData();
final SignedBlockAndState block = created.get(0);
assertThat(data)
.isEqualTo(
new SignedBeaconBlockPhase0(
new BeaconBlock(block.getBlock().getMessage()),
new BLSSignature(block.getBlock().getSignature())));
assertThat(data).isEqualTo(SignedBeaconBlock.create(block.getBlock()));

assertThat(response.header(HEADER_CONSENSUS_VERSION)).isEqualTo(Version.phase0.name());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void handle(@NotNull final Context ctx) throws Exception {
ctx.header(Header.CACHE_CONTROL, CACHE_NONE);

try {
SafeFuture<Set<SignedBeaconBlock>> future =
SafeFuture<Set<SignedBeaconBlock<?>>> future =
chainDataProvider.getAllBlocksAtSlot(pathParamMap.get(SLOT));
ctx.future(
future.thenApplyChecked(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ public GetBlock(final ChainDataProvider chainDataProvider, final JsonProvider js
@Override
public void handle(@NotNull final Context ctx) throws Exception {
final Map<String, String> pathParams = ctx.pathParamMap();
final SafeFuture<Optional<SignedBeaconBlock>> future =
final SafeFuture<Optional<SignedBeaconBlock<?>>> future =
chainDataProvider.getBlock(pathParams.get(PARAM_BLOCK_ID));
handleOptionalResult(ctx, future, this::handleResult, SC_NOT_FOUND);
}

private Optional<String> handleResult(Context ctx, final SignedBeaconBlock response)
private Optional<String> handleResult(Context ctx, final SignedBeaconBlock<?> response)
throws JsonProcessingException {
if (!chainDataProvider
.getMilestoneAtSlot(response.getMessage().slot)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void handle(final Context ctx) throws Exception {
return;
}

final SignedBeaconBlock signedBeaconBlock =
final SignedBeaconBlock<?> signedBeaconBlock =
validatorDataProvider.parseBlock(jsonProvider, ctx.body());

ctx.future(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ public void handle(@NotNull final Context ctx) throws Exception {
ctx, future, this::handleSszResult, this::resultFilename, SC_NOT_FOUND);

} else {
final SafeFuture<Optional<SignedBeaconBlock>> future =
final SafeFuture<Optional<SignedBeaconBlock<?>>> future =
chainDataProvider.getBlockV2(blockIdentifier);
handleOptionalResult(ctx, future, this::handleJsonResult, SC_NOT_FOUND);
}
}

private Optional<String> handleJsonResult(Context ctx, final SignedBeaconBlock response)
private Optional<String> handleJsonResult(Context ctx, final SignedBeaconBlock<?> response)
throws JsonProcessingException {
final Version version = chainDataProvider.getVersionAtSlot(response.getMessage().slot);
ctx.header(HEADER_CONSENSUS_VERSION, version.name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
import org.mockito.ArgumentCaptor;
import tech.pegasys.teku.api.SyncDataProvider;
import tech.pegasys.teku.api.ValidatorDataProvider;
import tech.pegasys.teku.api.schema.BeaconBlock;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.api.schema.ValidatorBlockResult;
import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.provider.JsonProvider;
import tech.pegasys.teku.spec.Spec;
Expand Down Expand Up @@ -78,7 +78,7 @@ void shouldReturnBadRequestIfArgumentNotJSON() throws Exception {
@Test
void shouldReturnBadRequestIfArgumentNotSignedBeaconBlock() throws Exception {
final String notASignedBlock =
jsonProvider.objectToJSON(new BeaconBlock(dataStructureUtil.randomBeaconBlock(3)));
jsonProvider.objectToJSON(new BeaconBlockPhase0(dataStructureUtil.randomBeaconBlock(3)));

when(syncDataProvider.isSyncing()).thenReturn(false);
when(context.body()).thenReturn(notASignedBlock);
Expand Down Expand Up @@ -130,7 +130,8 @@ void shouldReturnAcceptedIfBlockFailsValidation() throws Exception {
}

private String buildSignedBeaconBlock() throws JsonProcessingException {
SignedBeaconBlock block = new SignedBeaconBlock(dataStructureUtil.randomSignedBeaconBlock(3));
SignedBeaconBlock<?> block =
SignedBeaconBlock.create(dataStructureUtil.randomSignedBeaconBlock(3));
return jsonProvider.objectToJSON(block);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import tech.pegasys.teku.api.schema.Attestation;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.api.schema.SignedVoluntaryExit;
import tech.pegasys.teku.api.schema.altair.SignedBeaconBlockAltair;
import tech.pegasys.teku.infrastructure.async.StubAsyncRunner;
import tech.pegasys.teku.infrastructure.events.EventChannels;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
Expand Down Expand Up @@ -96,8 +95,8 @@ public class EventSubscriptionManagerTest {
new FinalizedCheckpointEvent(data.randomBytes32(), data.randomBytes32(), epoch);

private final SyncState sampleSyncState = SyncState.IN_SYNC;
private final SignedBeaconBlock sampleBlock =
new SignedBeaconBlockAltair(data.randomSignedBeaconBlock(0));
private final SignedBeaconBlock<?> sampleBlock =
SignedBeaconBlock.create(data.randomSignedBeaconBlock(0));
private final Attestation sampleAttestation = new Attestation(data.randomAttestation(0));
private final SignedVoluntaryExit sampleVoluntaryExit =
new SignedVoluntaryExit(data.randomSignedVoluntaryExit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import tech.pegasys.teku.api.response.v1.validator.GetNewBlockResponse;
import tech.pegasys.teku.api.schema.BLSSignature;
import tech.pegasys.teku.api.schema.BeaconBlock;
import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0;
import tech.pegasys.teku.beaconrestapi.schema.BadRequest;
import tech.pegasys.teku.bls.BLSTestUtil;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
Expand Down Expand Up @@ -80,7 +81,8 @@ void shouldReturnBlockWithoutGraffiti() throws Exception {
Map.of(RANDAO_REVEAL, List.of(signature.toHexString()));
Optional<BeaconBlock> optionalBeaconBlock =
Optional.of(
new BeaconBlock(dataStructureUtil.randomBeaconBlock(dataStructureUtil.randomLong())));
new BeaconBlockPhase0(
dataStructureUtil.randomBeaconBlock(dataStructureUtil.randomLong())));
when(context.queryParamMap()).thenReturn(queryParams);
when(context.pathParamMap()).thenReturn(pathParams);
when(provider.getMilestoneAtSlot(UInt64.ONE)).thenReturn(SpecMilestone.PHASE0);
Expand All @@ -105,7 +107,8 @@ void shouldReturnBlockWithGraffiti() throws Exception {
List.of(graffiti.toHexString()));
Optional<BeaconBlock> optionalBeaconBlock =
Optional.of(
new BeaconBlock(dataStructureUtil.randomBeaconBlock(dataStructureUtil.randomLong())));
new BeaconBlockPhase0(
dataStructureUtil.randomBeaconBlock(dataStructureUtil.randomLong())));
when(context.queryParamMap()).thenReturn(params);
when(context.pathParamMap()).thenReturn(Map.of(SLOT, "1"));
when(provider.getMilestoneAtSlot(UInt64.ONE)).thenReturn(SpecMilestone.PHASE0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ public SafeFuture<Optional<BlockHeader>> getBlockHeader(final String slotParamet
.thenApply(maybeBlock -> maybeBlock.map(block -> new BlockHeader(block, true)));
}

public SafeFuture<Optional<SignedBeaconBlock>> getBlock(final String slotParameter) {
public SafeFuture<Optional<SignedBeaconBlock<?>>> getBlock(final String slotParameter) {
return defaultBlockSelectorFactory
.defaultBlockSelector(slotParameter)
.getSingleBlock()
.thenApply(maybeBlock -> maybeBlock.map(SignedBeaconBlock::new));
.thenApply(maybeBlock -> maybeBlock.map(schemaObjectProvider::getSignedBeaconBlock));
}

public SafeFuture<Optional<SignedBeaconBlock>> getBlockV2(final String slotParameter) {
public SafeFuture<Optional<SignedBeaconBlock<?>>> getBlockV2(final String slotParameter) {
return defaultBlockSelectorFactory
.defaultBlockSelector(slotParameter)
.getSingleBlock()
Expand Down Expand Up @@ -201,7 +201,7 @@ public SafeFuture<Optional<SszResponse>> getBeaconStateSsz(final String stateIdP
spec.atSlot(state.getSlot()).getMilestone())));
}

public SafeFuture<Set<SignedBeaconBlock>> getAllBlocksAtSlot(final String slot) {
public SafeFuture<Set<SignedBeaconBlock<?>>> getAllBlocksAtSlot(final String slot) {
if (slot.startsWith("0x")) {
throw new BadRequestException(
String.format("block roots are not currently supported: %s", slot));
Expand All @@ -211,7 +211,9 @@ public SafeFuture<Set<SignedBeaconBlock>> getAllBlocksAtSlot(final String slot)
.getBlock()
.thenApply(
blockList ->
blockList.stream().map(SignedBeaconBlock::new).collect(Collectors.toSet()));
blockList.stream()
.map(schemaObjectProvider::getSignedBeaconBlock)
.collect(Collectors.toSet()));
}
}

Expand All @@ -230,7 +232,7 @@ public SafeFuture<Optional<SszResponse>> getBeaconStateSszByBlockRoot(
spec.atSlot(state.getSlot()).getMilestone())));
}

public boolean isFinalized(final SignedBeaconBlock signedBeaconBlock) {
public boolean isFinalized(final SignedBeaconBlock<?> signedBeaconBlock) {
return combinedChainDataClient.isFinalized(signedBeaconBlock.getMessage().slot);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,20 @@

package tech.pegasys.teku.api;

import tech.pegasys.teku.api.schema.BLSSignature;
import tech.pegasys.teku.api.schema.BeaconBlock;
import tech.pegasys.teku.api.schema.BeaconBlockBody;
import tech.pegasys.teku.api.schema.BeaconState;
import tech.pegasys.teku.api.schema.SignedBeaconBlock;
import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair;
import tech.pegasys.teku.api.schema.altair.BeaconBlockBodyAltair;
import tech.pegasys.teku.api.schema.altair.BeaconStateAltair;
import tech.pegasys.teku.api.schema.merge.BeaconBlockBodyMerge;
import tech.pegasys.teku.api.schema.merge.BeaconBlockMerge;
import tech.pegasys.teku.api.schema.merge.BeaconStateMerge;
import tech.pegasys.teku.api.schema.phase0.BeaconBlockPhase0;
import tech.pegasys.teku.api.schema.phase0.BeaconStatePhase0;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.Spec;
import tech.pegasys.teku.spec.SpecMilestone;

/**
* Takes objects from Internal layers and converts to an appropriate schema object.
Expand All @@ -37,28 +40,40 @@ public SchemaObjectProvider(final Spec spec) {
this.spec = spec;
}

public SignedBeaconBlock getSignedBeaconBlock(
public SignedBeaconBlock<?> getSignedBeaconBlock(
final tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock internalBlock) {
return new SignedBeaconBlock(
getBeaconBlock(internalBlock.getMessage()), new BLSSignature(internalBlock.getSignature()));

return SignedBeaconBlock.create(internalBlock);
}

public BeaconBlock getBeaconBlock(
final tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock block) {
if (spec.atSlot(block.getSlot()).getMilestone().equals(SpecMilestone.ALTAIR)) {
return new BeaconBlockAltair(
block.getSlot(),
block.getProposerIndex(),
block.getParentRoot(),
block.getStateRoot(),
getBeaconBlockBodyAltair(block.getBody()));
final UInt64 slot = block.getSlot();
switch (spec.atSlot(slot).getMilestone()) {
case PHASE0:
return new BeaconBlockPhase0(
block.getSlot(),
block.getProposerIndex(),
block.getParentRoot(),
block.getStateRoot(),
new BeaconBlockBody(block.getBody()));
case ALTAIR:
return new BeaconBlockAltair(
block.getSlot(),
block.getProposerIndex(),
block.getParentRoot(),
block.getStateRoot(),
getBeaconBlockBodyAltair(block.getBody()));
case MERGE:
return new BeaconBlockMerge(
block.getSlot(),
block.getProposerIndex(),
block.getParentRoot(),
block.getStateRoot(),
getBeaconBlockBodyMerge(block.getBody()));
default:
throw new IllegalArgumentException("Unsupported milestone for slot " + slot);
}
return new BeaconBlock(
block.getSlot(),
block.getProposerIndex(),
block.getParentRoot(),
block.getStateRoot(),
new BeaconBlockBody(block.getBody()));
}

private BeaconBlockBodyAltair getBeaconBlockBodyAltair(
Expand All @@ -68,11 +83,25 @@ private BeaconBlockBodyAltair getBeaconBlockBodyAltair(
.required(body));
}

private BeaconBlockBodyMerge getBeaconBlockBodyMerge(
final tech.pegasys.teku.spec.datastructures.blocks.blockbody.BeaconBlockBody body) {
return new BeaconBlockBodyMerge(
tech.pegasys.teku.spec.datastructures.blocks.blockbody.versions.merge.BeaconBlockBodyMerge
.required(body));
}

public BeaconState getBeaconState(
final tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState state) {
if (spec.atSlot(state.getSlot()).getMilestone().equals(SpecMilestone.ALTAIR)) {
return new BeaconStateAltair(state);
final UInt64 slot = state.getSlot();
switch (spec.atSlot(slot).getMilestone()) {
case PHASE0:
return new BeaconStatePhase0(state);
case ALTAIR:
return new BeaconStateAltair(state);
case MERGE:
return new BeaconStateMerge(state);
default:
throw new IllegalArgumentException("Unsupported milestone for slot " + slot);
}
return new BeaconStatePhase0(state);
}
}
Loading