Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into longvalue-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfyone committed Jan 21, 2025
2 parents 7f0f50d + 1e371ee commit e891c36
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import tech.pegasys.teku.spec.datastructures.operations.SignedVoluntaryExit;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache;
import tech.pegasys.teku.spec.datastructures.state.versions.electra.PendingPartialWithdrawal;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.datastructures.type.SszKZGProof;
import tech.pegasys.teku.spec.executionlayer.ExecutionLayerBlockProductionManager;
Expand Down Expand Up @@ -146,7 +147,7 @@ public Function<BeaconBlockBodyBuilder, SafeFuture<Void>> createSelector(
final SszList<SignedVoluntaryExit> voluntaryExits =
voluntaryExitPool.getItemsForBlock(
blockSlotState,
exit -> !exitedValidators.contains(exit.getMessage().getValidatorIndex()),
exit -> voluntaryExitPredicate(blockSlotState, exitedValidators, exit),
exit -> exitedValidators.add(exit.getMessage().getValidatorIndex()));

bodyBuilder
Expand Down Expand Up @@ -204,6 +205,25 @@ public Function<BeaconBlockBodyBuilder, SafeFuture<Void>> createSelector(
};
}

private boolean voluntaryExitPredicate(
final BeaconState blockSlotState,
final Set<UInt64> exitedValidators,
final SignedVoluntaryExit exit) {
final UInt64 validatorIndex = exit.getMessage().getValidatorIndex();
if (exitedValidators.contains(validatorIndex)) {
return false;
}
// if there is a pending withdrawal, the exit is not valid for inclusion in a block.
return blockSlotState
.toVersionElectra()
.map(
beaconStateElectra ->
beaconStateElectra.getPendingPartialWithdrawals().stream()
.map(PendingPartialWithdrawal::getValidatorIndex)
.noneMatch(index -> index == validatorIndex.intValue()))
.orElse(true);
}

private SafeFuture<Void> setExecutionData(
final Optional<ExecutionPayloadContext> executionPayloadContext,
final BeaconBlockBodyBuilder bodyBuilder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import tech.pegasys.teku.spec.datastructures.operations.versions.altair.SignedContributionAndProof;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache;
import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra;
import tech.pegasys.teku.spec.datastructures.type.SszKZGCommitment;
import tech.pegasys.teku.spec.datastructures.type.SszKZGProof;
import tech.pegasys.teku.spec.executionlayer.ExecutionLayerBlockProductionManager;
Expand Down Expand Up @@ -264,6 +265,39 @@ void shouldNotSelectOperationsWhenNoneAreAvailable() {
assertThat(bodyBuilder.blsToExecutionChanges).isEmpty();
}

@Test
void shouldNotSelectVoluntaryExitWhenValidatorHasPendingWithdrawal() {
final UInt64 slot = UInt64.ONE;
final MutableBeaconStateElectra blockSlotState =
dataStructureUtil.randomBeaconState(slot).toVersionElectra().get().createWritableCopy();
blockSlotState
.getPendingPartialWithdrawals()
.append(dataStructureUtil.randomPendingPartialWithdrawal(1));
final SignedVoluntaryExit voluntaryExit =
dataStructureUtil.randomSignedVoluntaryExit(UInt64.valueOf(1));
final ExecutionPayload randomExecutionPayload = dataStructureUtil.randomExecutionPayload();
final UInt256 blockExecutionValue = dataStructureUtil.randomUInt256();

addToPool(voluntaryExitPool, voluntaryExit);
prepareBlockProductionWithPayload(
randomExecutionPayload,
executionPayloadContext,
blockSlotState,
Optional.of(blockExecutionValue));

safeJoin(
factory
.createSelector(
parentRoot,
blockSlotState,
randaoReveal,
Optional.of(defaultGraffiti),
Optional.empty(),
BlockProductionPerformance.NOOP)
.apply(bodyBuilder));
assertThat(bodyBuilder.voluntaryExits).isEmpty();
}

@Test
void shouldIncludeValidOperations() {
final UInt64 slot = UInt64.valueOf(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public class ReferenceTestFinder {
TestFork.ALTAIR,
TestFork.BELLATRIX,
TestFork.CAPELLA,
TestFork.DENEB); // TODO: Add Electra fork tests back
TestFork.DENEB,
TestFork.ELECTRA);

@MustBeClosed
public static Stream<TestDefinition> findReferenceTests() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2641,6 +2641,15 @@ public PendingPartialWithdrawal randomPendingPartialWithdrawal() {
SszUInt64.of(randomUInt64()));
}

public PendingPartialWithdrawal randomPendingPartialWithdrawal(final long validatorIndex) {
return getElectraSchemaDefinitions(randomSlot())
.getPendingPartialWithdrawalSchema()
.create(
SszUInt64.of(UInt64.valueOf(validatorIndex)),
SszUInt64.of(randomUInt64()),
SszUInt64.of(randomUInt64()));
}

public UInt64 randomBlobSidecarIndex() {
return randomUInt64(
spec.forMilestone(spec.getForkSchedule().getHighestSupportedMilestone())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public Optional<RpcException> validateRequest(

final long requestedCount = calculateRequestedCount(request, maxBlobsPerBlock);

if (requestedCount > maxRequestBlobSidecars) {
// handle overflows
if (requestedCount < 0 || requestedCount > maxRequestBlobSidecars) {
requestCounter.labels("count_too_big").inc();
return Optional.of(
new RpcException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,43 @@ public void validateRequest_shouldRejectRequestWhenCountIsTooBig() {
"Only a maximum of %s blob sidecars can be requested per request",
maxRequestBlobSidecars)));

final long rateLimitedCount =
final long countTooBigCount =
metricsSystem.getCounterValue(
TekuMetricCategory.NETWORK,
"rpc_blob_sidecars_by_range_requests_total",
"count_too_big");

assertThat(rateLimitedCount).isOne();
assertThat(countTooBigCount).isOne();
}

@TestTemplate
public void validateRequest_shouldRejectRequestForVeryLargeValue() {
final UInt64 maxRequestBlobSidecars =
UInt64.valueOf(
SpecConfigDeneb.required(spec.forMilestone(specMilestone).getConfig())
.getMaxRequestBlobSidecars());
final BlobSidecarsByRangeRequestMessage request =
new BlobSidecarsByRangeRequestMessage(
// bypass ArithmeticException when calculating maxSlot
startSlot, UInt64.MAX_VALUE.minus(startSlot), maxBlobsPerBlock);

final Optional<RpcException> result = handler.validateRequest(protocolId, request);

assertThat(result)
.hasValue(
new RpcException(
INVALID_REQUEST_CODE,
String.format(
"Only a maximum of %s blob sidecars can be requested per request",
maxRequestBlobSidecars)));

final long countTooBigCount =
metricsSystem.getCounterValue(
TekuMetricCategory.NETWORK,
"rpc_blob_sidecars_by_range_requests_total",
"count_too_big");

assertThat(countTooBigCount).isOne();
}

@TestTemplate
Expand Down

0 comments on commit e891c36

Please sign in to comment.