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

create EphemerySlotValidationService and test #8759

Merged
merged 11 commits into from
Oct 31, 2024
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 @@ -532,6 +533,7 @@ public void initAll() {
initRestAPI();
initOperationsReOrgManager();
initValidatorIndexCacheTracker();
initEphemeryValidationService();
}

private void initKeyValueStore() {
Expand Down Expand Up @@ -1148,6 +1150,15 @@ protected void initP2PNetwork() {
new LocalOperationAcceptedFilter<>(p2pNetwork::publishSignedBlsToExecutionChange));
}

protected void initEphemeryValidationService() {
Optional<Eth2Network> network = beaconConfig.eth2NetworkConfig().getEth2Network();
gconnect marked this conversation as resolved.
Show resolved Hide resolved
if (network.isPresent() && network.equals(Optional.of(Eth2Network.EPHEMERY))) {
final EphemerySlotValidationService slotValidationService =
gconnect marked this conversation as resolved.
Show resolved Hide resolved
new EphemerySlotValidationService();
eventChannels.subscribe(SlotEventsChannel.class, slotValidationService);
gconnect marked this conversation as resolved.
Show resolved Hide resolved
}
}

protected Eth2P2PNetworkBuilder createEth2P2PNetworkBuilder() {
return Eth2P2PNetworkBuilder.create();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 {

public EphemerySlotValidationService() {}
gconnect marked this conversation as resolved.
Show resolved Hide resolved

@Override
public void onSlot(final UInt64 slot) {
if (slot.compareTo(MAX_EPHEMERY_SLOT) > 0) {
gconnect marked this conversation as resolved.
Show resolved Hide resolved
throw new IllegalStateException(
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,71 @@
/*
* 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.assertThatCode;
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).isPresent().contains(Eth2Network.EPHEMERY);
gconnect marked this conversation as resolved.
Show resolved Hide resolved
assertThatThrownBy(() -> ephemerySlotValidationService.onSlot(invalidSlot))
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining(
String.format(
"Slot %s exceeds maximum allowed slot %s for ephemery network",
invalidSlot, MAX_EPHEMERY_SLOT));
}

@Test
public void onSlot_shouldNotThrowException_forNonEphemeryNetwork() {
final Eth2Network network = Eth2Network.SEPOLIA;
assertThat(network).isNotEqualTo(Eth2Network.EPHEMERY);
assertThatCode(() -> {}).doesNotThrowAnyException();
gconnect marked this conversation as resolved.
Show resolved Hide resolved
}

@Test
void shouldCompleteWhenServiceStartsAndStops() {
final SafeFuture<?> startFuture = ephemerySlotValidationService.doStart();
final SafeFuture<?> stopFuture = ephemerySlotValidationService.doStop();
assertTrue(startFuture.isDone());
gconnect marked this conversation as resolved.
Show resolved Hide resolved
assertTrue(stopFuture.isDone());
}
}