Skip to content

Commit

Permalink
create EphemerySlotValidationService and test (#8759)
Browse files Browse the repository at this point in the history
Signed-off-by: gconnect <agatevureglory@gmail.com>
Co-authored-by: Paul Harris <paul.harris@consensys.net>
  • Loading branch information
gconnect and rolfyone authored Oct 31, 2024
1 parent 76fc318 commit 92cebd3
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
import tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult;
import tech.pegasys.teku.spec.logic.common.util.BlockRewardCalculatorUtil;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.teku.statetransition.EpochCachePrimer;
import tech.pegasys.teku.statetransition.LocalOperationAcceptedFilter;
import tech.pegasys.teku.statetransition.MappedOperationPool;
Expand Down Expand Up @@ -219,6 +220,7 @@
public class BeaconChainController extends Service implements BeaconChainControllerFacade {

private static final Logger LOG = LogManager.getLogger();
private final EphemerySlotValidationService ephemerySlotValidationService;

protected static final String KEY_VALUE_STORE_SUBDIRECTORY = "kvstore";

Expand Down Expand Up @@ -335,6 +337,7 @@ public BeaconChainController(
"future_items_size",
"Current number of items held for future slots, labelled by type",
"type");
this.ephemerySlotValidationService = new EphemerySlotValidationService();
}

@Override
Expand Down Expand Up @@ -364,6 +367,12 @@ protected void startServices() {
blobSidecar ->
recentBlobSidecarsFetcher.cancelRecentBlobSidecarRequest(
new BlobIdentifier(blobSidecar.getBlockRoot(), blobSidecar.getIndex())));

final Optional<Eth2Network> network = beaconConfig.eth2NetworkConfig().getEth2Network();
if (network.isPresent() && network.get() == Eth2Network.EPHEMERY) {
LOG.debug("BeaconChainController: subscribing to slot events");
eventChannels.subscribe(SlotEventsChannel.class, ephemerySlotValidationService);
}
SafeFuture.allOfFailFast(
attestationManager.start(),
p2pNetwork.start(),
Expand Down Expand Up @@ -401,6 +410,7 @@ protected SafeFuture<?> doStop() {
attestationManager.stop(),
p2pNetwork.stop(),
timerService.stop(),
ephemerySlotValidationService.doStop(),
SafeFuture.fromRunnable(
() -> terminalPowBlockMonitor.ifPresent(TerminalPowBlockMonitor::stop)))
.thenRun(forkChoiceExecutor::stop);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.services.beaconchain;

public class EphemeryLifecycleException extends RuntimeException {
public EphemeryLifecycleException(final String format) {
super(format);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.services.beaconchain;

import static tech.pegasys.teku.networks.EphemeryNetwork.MAX_EPHEMERY_SLOT;

import tech.pegasys.teku.ethereum.events.SlotEventsChannel;
import tech.pegasys.teku.infrastructure.async.SafeFuture;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.service.serviceutils.Service;

public class EphemerySlotValidationService extends Service implements SlotEventsChannel {

@Override
public void onSlot(final UInt64 slot) {
if (slot.isGreaterThan(MAX_EPHEMERY_SLOT)) {
throw new EphemeryLifecycleException(
String.format(
"Slot %s exceeds maximum allowed slot %s for ephemery network",
slot, MAX_EPHEMERY_SLOT));
}
}

@Override
protected SafeFuture<?> doStart() {
return SafeFuture.COMPLETE;
}

@Override
protected SafeFuture<?> doStop() {
return SafeFuture.COMPLETE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.services.beaconchain;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static tech.pegasys.teku.networks.EphemeryNetwork.MAX_EPHEMERY_SLOT;

import java.util.Optional;
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.networks.Eth2Network;

class EphemerySlotValidationServiceTest {
private EphemerySlotValidationService ephemerySlotValidationService;

@BeforeEach
void setUp() {
ephemerySlotValidationService = new EphemerySlotValidationService();
}

@Test
public void onSlot_shouldNotThrow_whenSlotIsValid() {
ephemerySlotValidationService.onSlot(UInt64.valueOf(MAX_EPHEMERY_SLOT));
}

@Test
public void onSlot_shouldThrowException_whenSlotExceedsMaxEphemerySlot_forEphemeryNetwork() {
final Eth2Network network = Eth2Network.EPHEMERY;
final Optional<Eth2Network> ephemeryNetwork = Optional.of(network);
final UInt64 invalidSlot = UInt64.valueOf(MAX_EPHEMERY_SLOT + 1);

assertThat(ephemeryNetwork).contains(Eth2Network.EPHEMERY);
assertThatThrownBy(() -> ephemerySlotValidationService.onSlot(invalidSlot))
.isInstanceOf(EphemeryLifecycleException.class)
.hasMessageContaining(
String.format(
"Slot %s exceeds maximum allowed slot %s for ephemery network",
invalidSlot, MAX_EPHEMERY_SLOT));
}

@Test
void shouldCompleteWhenServiceStartsAndStops() {
final SafeFuture<?> startFuture = ephemerySlotValidationService.doStart();
assertTrue(startFuture.isDone());
final SafeFuture<?> stopFuture = ephemerySlotValidationService.doStop();
assertTrue(stopFuture.isDone());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import tech.pegasys.teku.infrastructure.exceptions.ExceptionUtil;
import tech.pegasys.teku.infrastructure.exceptions.FatalServiceFailureException;
import tech.pegasys.teku.infrastructure.logging.StatusLogger;
import tech.pegasys.teku.services.beaconchain.EphemeryLifecycleException;
import tech.pegasys.teku.storage.server.DatabaseStorageException;
import tech.pegasys.teku.storage.server.ShuttingDownException;

Expand Down Expand Up @@ -85,6 +86,9 @@ private void handleException(final Throwable exception, final String subscriberD
} else if (exception instanceof OutOfMemoryError) {
statusLog.fatalError(subscriberDescription, exception);
System.exit(ERROR_EXIT_CODE);
} else if (exception instanceof EphemeryLifecycleException) {
statusLog.fatalError(subscriberDescription, exception);
System.exit(ERROR_EXIT_CODE);
} else if (exception instanceof ShuttingDownException) {
LOG.debug("Shutting down", exception);
} else if (isExpectedNettyError(exception)) {
Expand Down

0 comments on commit 92cebd3

Please sign in to comment.