diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java index bedbc7f138a..29d1f68f6a3 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/Spec.java @@ -960,7 +960,7 @@ public Optional getMaxBlobsPerBlock(final UInt64 slot) { public UInt64 computeSubnetForBlobSidecar(final BlobSidecar blobSidecar) { return blobSidecar .getIndex() - .mod(atSlot(blobSidecar.getSlot()).miscHelpers().getBlobSidecarSubnetCount()); + .mod(atSlot(blobSidecar.getSlot()).miscHelpers().getBlobSidecarSubnetCount().orElseThrow()); } public Optional computeFirstSlotWithBlobSupport() { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java index 3f5422df0ef..1e411f8591f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java @@ -396,8 +396,8 @@ public int getMaxBlobsPerBlock() { throw new UnsupportedOperationException("No Blob Sidecars before Deneb"); } - public int getBlobSidecarSubnetCount() { - throw new UnsupportedOperationException("No Blob Sidecars before Deneb"); + public Optional getBlobSidecarSubnetCount() { + return Optional.empty(); } public int getBlobKzgCommitmentsCount(final SignedBeaconBlock signedBeaconBlock) { diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/helpers/MiscHelpersDeneb.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/helpers/MiscHelpersDeneb.java index 4708018e481..85f63b57a5a 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/helpers/MiscHelpersDeneb.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/deneb/helpers/MiscHelpersDeneb.java @@ -222,8 +222,8 @@ public int getMaxBlobsPerBlock() { } @Override - public int getBlobSidecarSubnetCount() { - return SpecConfigDeneb.required(specConfig).getBlobSidecarSubnetCount(); + public Optional getBlobSidecarSubnetCount() { + return Optional.of(SpecConfigDeneb.required(specConfig).getBlobSidecarSubnetCount()); } @Override diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java index 77ba81f3f68..b8f56afcb71 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java @@ -97,7 +97,7 @@ public int getMaxBlobsPerBlock() { } @Override - public int getBlobSidecarSubnetCount() { - return SpecConfigElectra.required(specConfig).getBlobSidecarSubnetCountElectra(); + public Optional getBlobSidecarSubnetCount() { + return Optional.of(SpecConfigElectra.required(specConfig).getBlobSidecarSubnetCountElectra()); } } diff --git a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManager.java b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManager.java index 3354593d0c2..de8c260cfbd 100644 --- a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManager.java +++ b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManager.java @@ -32,8 +32,8 @@ import tech.pegasys.teku.networking.p2p.gossip.GossipNetwork; import tech.pegasys.teku.networking.p2p.gossip.TopicChannel; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.SpecVersion; -import tech.pegasys.teku.spec.config.SpecConfigDeneb; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecarSchema; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; @@ -68,8 +68,11 @@ public static BlobSidecarGossipManager create( .getBlobSidecarSchema(); final Int2ObjectMap> subnetIdToTopicHandler = new Int2ObjectOpenHashMap<>(); - final SpecConfigDeneb specConfigDeneb = SpecConfigDeneb.required(forkSpecVersion.getConfig()); - IntStream.range(0, specConfigDeneb.getBlobSidecarSubnetCount()) + final SpecMilestone specMilestone = spec.atEpoch(forkInfo.getFork().getEpoch()).getMilestone(); + final int blobSidecarSubnetCount = + spec.forMilestone(specMilestone).miscHelpers().getBlobSidecarSubnetCount().orElseThrow(); + + IntStream.range(0, blobSidecarSubnetCount) .forEach( subnetId -> { final Eth2TopicHandler topicHandler = diff --git a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilter.java b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilter.java index 260beb80296..1aa08b34474 100644 --- a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilter.java +++ b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilter.java @@ -24,6 +24,7 @@ import tech.pegasys.teku.networking.eth2.gossip.encoding.GossipEncoding; import tech.pegasys.teku.networking.p2p.libp2p.gossip.GossipTopicFilter; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; import tech.pegasys.teku.storage.client.RecentChainData; @@ -52,7 +53,9 @@ private Set computeRelevantTopics( final RecentChainData recentChainData, final GossipEncoding gossipEncoding) { final ForkInfo forkInfo = recentChainData.getCurrentForkInfo().orElseThrow(); final Bytes4 forkDigest = forkInfo.getForkDigest(spec); - final Set topics = getAllTopics(gossipEncoding, forkDigest, spec); + final SpecMilestone specMilestone = + recentChainData.getMilestoneByForkDigest(forkDigest).orElseThrow(); + final Set topics = getAllTopics(gossipEncoding, forkDigest, spec, specMilestone); spec.getForkSchedule().getForks().stream() .filter(fork -> fork.getEpoch().isGreaterThanOrEqualTo(forkInfo.getFork().getEpoch())) .forEach( @@ -62,7 +65,7 @@ private Set computeRelevantTopics( .miscHelpers() .computeForkDigest( futureFork.getCurrentVersion(), forkInfo.getGenesisValidatorsRoot()); - topics.addAll(getAllTopics(gossipEncoding, futureForkDigest, spec)); + topics.addAll(getAllTopics(gossipEncoding, futureForkDigest, spec, specMilestone)); }); return topics; } diff --git a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/GossipTopics.java b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/GossipTopics.java index 8f71a1ac466..3f79636bfad 100644 --- a/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/GossipTopics.java +++ b/networking/eth2/src/main/java/tech/pegasys/teku/networking/eth2/gossip/topics/GossipTopics.java @@ -18,6 +18,7 @@ import tech.pegasys.teku.infrastructure.bytes.Bytes4; import tech.pegasys.teku.networking.eth2.gossip.encoding.GossipEncoding; import tech.pegasys.teku.spec.Spec; +import tech.pegasys.teku.spec.SpecMilestone; import tech.pegasys.teku.spec.constants.NetworkConstants; /** @@ -64,7 +65,10 @@ public static String getBlobSidecarSubnetTopic( } public static Set getAllTopics( - final GossipEncoding gossipEncoding, final Bytes4 forkDigest, final Spec spec) { + final GossipEncoding gossipEncoding, + final Bytes4 forkDigest, + final Spec spec, + final SpecMilestone specMilestone) { final Set topics = new HashSet<>(); for (int i = 0; i < spec.getNetworkingConfig().getAttestationSubnetCount(); i++) { @@ -73,11 +77,13 @@ public static Set getAllTopics( for (int i = 0; i < NetworkConstants.SYNC_COMMITTEE_SUBNET_COUNT; i++) { topics.add(getSyncCommitteeSubnetTopic(forkDigest, i, gossipEncoding)); } - if (spec.getNetworkingConfigDeneb().isPresent()) { - for (int i = 0; i < spec.getNetworkingConfigDeneb().get().getBlobSidecarSubnetCount(); i++) { - topics.add(getBlobSidecarSubnetTopic(forkDigest, i, gossipEncoding)); - } - } + + spec.forMilestone(specMilestone) + .miscHelpers() + .getBlobSidecarSubnetCount() + .ifPresent( + integer -> addBlobSidecarSubnetTopics(integer, topics, forkDigest, gossipEncoding)); + for (GossipTopicName topicName : GossipTopicName.values()) { topics.add(GossipTopics.getTopic(forkDigest, topicName, gossipEncoding)); } @@ -98,4 +104,14 @@ public static Bytes4 extractForkDigest(final String topic) throws IllegalArgumen return Bytes4.fromHexString(forkDigest); } + + private static void addBlobSidecarSubnetTopics( + final int blobSidecarSubnetCount, + final Set topics, + final Bytes4 forkDigest, + final GossipEncoding gossipEncoding) { + for (int i = 0; i < blobSidecarSubnetCount; i++) { + topics.add(getBlobSidecarSubnetTopic(forkDigest, i, gossipEncoding)); + } + } } diff --git a/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManagerTest.java b/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManagerTest.java index 3c42b72abe5..8eb22792125 100644 --- a/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManagerTest.java +++ b/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/BlobSidecarGossipManagerTest.java @@ -30,7 +30,7 @@ import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestTemplate; import tech.pegasys.teku.infrastructure.async.SafeFuture; import tech.pegasys.teku.infrastructure.async.StubAsyncRunner; import tech.pegasys.teku.infrastructure.unsigned.UInt64; @@ -41,9 +41,10 @@ import tech.pegasys.teku.networking.p2p.gossip.TopicChannel; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; -import tech.pegasys.teku.spec.TestSpecFactory; -import tech.pegasys.teku.spec.config.SpecConfig; +import tech.pegasys.teku.spec.TestSpecContext; +import tech.pegasys.teku.spec.TestSpecInvocationContextProvider; import tech.pegasys.teku.spec.config.SpecConfigDeneb; +import tech.pegasys.teku.spec.config.SpecConfigElectra; import tech.pegasys.teku.spec.datastructures.blobs.versions.deneb.BlobSidecar; import tech.pegasys.teku.spec.datastructures.state.ForkInfo; import tech.pegasys.teku.spec.util.DataStructureUtil; @@ -52,31 +53,30 @@ import tech.pegasys.teku.storage.storageSystem.InMemoryStorageSystemBuilder; import tech.pegasys.teku.storage.storageSystem.StorageSystem; +@TestSpecContext(milestone = {SpecMilestone.DENEB, SpecMilestone.ELECTRA}) public class BlobSidecarGossipManagerTest { private static final Pattern BLOB_SIDECAR_TOPIC_PATTERN = Pattern.compile("blob_sidecar_(\\d+)"); - private final Spec spec = TestSpecFactory.createMainnetDeneb(); - private final StorageSystem storageSystem = InMemoryStorageSystemBuilder.buildDefault(spec); - private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); - @SuppressWarnings("unchecked") private final OperationProcessor processor = mock(OperationProcessor.class); private final GossipNetwork gossipNetwork = mock(GossipNetwork.class); private final GossipEncoding gossipEncoding = GossipEncoding.SSZ_SNAPPY; - private final Map topicChannels = new HashMap<>(); - private final StubAsyncRunner asyncRunner = new StubAsyncRunner(); - private final ForkInfo forkInfo = - new ForkInfo(spec.fork(UInt64.ZERO), dataStructureUtil.randomBytes32()); - + private Spec spec; + private DataStructureUtil dataStructureUtil; private BlobSidecarGossipManager blobSidecarGossipManager; + private SpecMilestone specMilestone; @BeforeEach - public void setup() { + public void setup(final TestSpecInvocationContextProvider.SpecContext specContext) { + spec = specContext.getSpec(); + dataStructureUtil = specContext.getDataStructureUtil(); + specMilestone = specContext.getSpecMilestone(); + final StorageSystem storageSystem = InMemoryStorageSystemBuilder.buildDefault(spec); storageSystem.chainUpdater().initializeGenesis(); // return TopicChannel mock for each blob_sidecar_ topic doAnswer( @@ -96,6 +96,8 @@ public void setup() { .subscribe(any(), any()); when(processor.process(any(), any())) .thenReturn(SafeFuture.completedFuture(InternalValidationResult.ACCEPT)); + final ForkInfo forkInfo = + new ForkInfo(spec.fork(UInt64.ZERO), dataStructureUtil.randomBytes32()); blobSidecarGossipManager = BlobSidecarGossipManager.create( storageSystem.recentChainData(), @@ -109,7 +111,7 @@ public void setup() { blobSidecarGossipManager.subscribe(); } - @Test + @TestTemplate public void testGossipingBlobSidecarPublishesToCorrectSubnet() { final BlobSidecar blobSidecar = dataStructureUtil.createRandomBlobSidecarBuilder().index(UInt64.ONE).build(); @@ -127,19 +129,18 @@ public void testGossipingBlobSidecarPublishesToCorrectSubnet() { }); } - @Test + @TestTemplate public void testGossipingBlobSidecarWithLargeIndexGossipToCorrectSubnet() { final BlobSidecar blobSidecar = dataStructureUtil.createRandomBlobSidecarBuilder().index(UInt64.valueOf(10)).build(); final Bytes serialized = gossipEncoding.encode(blobSidecar); safeJoin(blobSidecarGossipManager.publishBlobSidecar(blobSidecar)); - final SpecConfig config = spec.forMilestone(SpecMilestone.DENEB).getConfig(); - final SpecConfigDeneb specConfigDeneb = SpecConfigDeneb.required(config); + final int blobSidecarSubnetCount = getBlobSidecarSubnetCount(); topicChannels.forEach( (subnetId, channel) -> { - if (subnetId == 10 % specConfigDeneb.getBlobSidecarSubnetCount()) { + if (subnetId == 10 % blobSidecarSubnetCount) { verify(channel).gossip(serialized); } else { verifyNoInteractions(channel); @@ -147,7 +148,7 @@ public void testGossipingBlobSidecarWithLargeIndexGossipToCorrectSubnet() { }); } - @Test + @TestTemplate public void testUnsubscribingClosesAllChannels() { blobSidecarGossipManager.unsubscribe(); @@ -159,7 +160,7 @@ public void testUnsubscribingClosesAllChannels() { }); } - @Test + @TestTemplate public void testAcceptingSidecarGossipIfOnTheCorrectTopic() { // topic handler for blob sidecars with subnet_id 1 final Eth2TopicHandler topicHandler = blobSidecarGossipManager.getTopicHandler(1); @@ -175,7 +176,7 @@ public void testAcceptingSidecarGossipIfOnTheCorrectTopic() { assertThat(validationResult).isEqualTo(InternalValidationResult.ACCEPT); } - @Test + @TestTemplate public void testRejectingSidecarGossipIfNotOnTheCorrectTopic() { // topic handler for blob sidecars with subnet_id 1 final Eth2TopicHandler topicHandler = blobSidecarGossipManager.getTopicHandler(1); @@ -190,4 +191,12 @@ public void testRejectingSidecarGossipIfNotOnTheCorrectTopic() { assertThat(validationResult.getDescription()) .hasValue("blob sidecar with subnet_id 2 does not match the topic subnet_id 1"); } + + private int getBlobSidecarSubnetCount() { + return specMilestone.isGreaterThanOrEqualTo(SpecMilestone.ELECTRA) + ? SpecConfigElectra.required(spec.forMilestone(SpecMilestone.ELECTRA).getConfig()) + .getBlobSidecarSubnetCountElectra() + : SpecConfigDeneb.required(spec.forMilestone(SpecMilestone.DENEB).getConfig()) + .getBlobSidecarSubnetCount(); + } } diff --git a/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilterTest.java b/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilterTest.java index 8dd30549a36..3b275ee7595 100644 --- a/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilterTest.java +++ b/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/topics/Eth2GossipTopicFilterTest.java @@ -27,12 +27,14 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestTemplate; import tech.pegasys.teku.infrastructure.bytes.Bytes4; import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecMilestone; +import tech.pegasys.teku.spec.TestSpecContext; import tech.pegasys.teku.spec.TestSpecFactory; +import tech.pegasys.teku.spec.TestSpecInvocationContextProvider; import tech.pegasys.teku.spec.config.SpecConfig; import tech.pegasys.teku.spec.config.SpecConfigDeneb; import tech.pegasys.teku.spec.datastructures.state.Fork; @@ -40,47 +42,69 @@ import tech.pegasys.teku.spec.util.DataStructureUtil; import tech.pegasys.teku.storage.client.RecentChainData; +@TestSpecContext(milestone = {SpecMilestone.DENEB, SpecMilestone.ELECTRA}) class Eth2GossipTopicFilterTest { - private final UInt64 denebForkEpoch = UInt64.valueOf(10); - private final Spec spec = TestSpecFactory.createMinimalWithDenebForkEpoch(denebForkEpoch); - private final List forks = spec.getForkSchedule().getForks(); - private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); - private final Bytes32 genesisValidatorsRoot = dataStructureUtil.randomBytes32(); - private final ForkInfo forkInfo = new ForkInfo(forks.get(0), genesisValidatorsRoot); - private final Fork nextFork = forks.get(1); private final RecentChainData recentChainData = mock(RecentChainData.class); - private final Bytes4 nextForkDigest = - spec.atEpoch(nextFork.getEpoch()) - .miscHelpers() - .computeForkDigest(nextFork.getCurrentVersion(), genesisValidatorsRoot); - - private final Eth2GossipTopicFilter filter = - new Eth2GossipTopicFilter(recentChainData, SSZ_SNAPPY, spec); + private final UInt64 currentForkEpoch = UInt64.valueOf(10); + private Spec spec; + private SpecMilestone specMilestone; + private DataStructureUtil dataStructureUtil; + private ForkInfo forkInfo; + private Eth2GossipTopicFilter filter; + private Bytes4 currentForkDigest; + private Bytes4 nextForkDigest; @BeforeEach - void setUp() { + void setUp(final TestSpecInvocationContextProvider.SpecContext specContext) { + specMilestone = specContext.getSpecMilestone(); + spec = + switch (specContext.getSpecMilestone()) { + case PHASE0 -> throw new IllegalArgumentException("Phase0 is an unsupported milestone"); + case ALTAIR -> throw new IllegalArgumentException("Altair is an unsupported milestone"); + case BELLATRIX -> + throw new IllegalArgumentException("Bellatrix is an unsupported milestone"); + case CAPELLA -> throw new IllegalArgumentException("Capella is an unsupported milestone"); + case DENEB -> TestSpecFactory.createMinimalWithDenebForkEpoch(currentForkEpoch); + case ELECTRA -> TestSpecFactory.createMinimalWithElectraForkEpoch(currentForkEpoch); + }; + dataStructureUtil = new DataStructureUtil(spec); + filter = new Eth2GossipTopicFilter(recentChainData, SSZ_SNAPPY, spec); + + final Bytes32 genesisValidatorsRoot = dataStructureUtil.randomBytes32(); + final List forks = spec.getForkSchedule().getForks(); + forkInfo = new ForkInfo(forks.get(0), genesisValidatorsRoot); + currentForkDigest = forkInfo.getForkDigest(spec); + + final Fork nextFork = forks.get(1); + nextForkDigest = + spec.atEpoch(nextFork.getEpoch()) + .miscHelpers() + .computeForkDigest(nextFork.getCurrentVersion(), genesisValidatorsRoot); + when(recentChainData.getCurrentForkInfo()).thenReturn(Optional.of(forkInfo)); when(recentChainData.getNextFork(forkInfo.getFork())).thenReturn(Optional.of(nextFork)); + when(recentChainData.getMilestoneByForkDigest(currentForkDigest)) + .thenReturn(Optional.of(specMilestone)); } - @Test + @TestTemplate void shouldNotAllowIrrelevantTopics() { assertThat(filter.isRelevantTopic("abc")).isFalse(); } - @Test + @TestTemplate void shouldNotRequireNextForkToBePresent() { when(recentChainData.getNextFork(any())).thenReturn(Optional.empty()); assertThat(filter.isRelevantTopic(getTopicName(GossipTopicName.BEACON_BLOCK))).isTrue(); } - @Test + @TestTemplate void shouldConsiderTopicsForNextForkRelevant() { assertThat(filter.isRelevantTopic(getNextForkTopicName(GossipTopicName.BEACON_BLOCK))).isTrue(); } - @Test + @TestTemplate void shouldConsiderTopicsForSignedContributionAndProofRelevant() { assertThat( filter.isRelevantTopic( @@ -88,7 +112,7 @@ void shouldConsiderTopicsForSignedContributionAndProofRelevant() { .isTrue(); } - @Test + @TestTemplate void shouldConsiderAllAttestationSubnetsRelevant() { for (int i = 0; i < spec.getNetworkingConfig().getAttestationSubnetCount(); i++) { assertThat(filter.isRelevantTopic(getTopicName(getAttestationSubnetTopicName(i)))).isTrue(); @@ -97,14 +121,14 @@ void shouldConsiderAllAttestationSubnetsRelevant() { } } - @Test + @TestTemplate void shouldConsiderAllSyncCommitteeSubnetsRelevant() { for (int i = 0; i < SYNC_COMMITTEE_SUBNET_COUNT; i++) { assertThat(filter.isRelevantTopic(getTopicName(getSyncCommitteeSubnetTopicName(i)))).isTrue(); } } - @Test + @TestTemplate void shouldConsiderAllBlobSidecarSubnetsRelevant() { final SpecConfig config = spec.forMilestone(SpecMilestone.DENEB).getConfig(); final SpecConfigDeneb specConfigDeneb = SpecConfigDeneb.required(config); @@ -113,24 +137,22 @@ void shouldConsiderAllBlobSidecarSubnetsRelevant() { } } - @Test + @TestTemplate void shouldNotConsiderBlobSidecarWithIncorrectSubnetIdRelevant() { - final SpecConfig config = spec.forMilestone(SpecMilestone.DENEB).getConfig(); - final SpecConfigDeneb specConfigDeneb = SpecConfigDeneb.required(config); + final int blobSidecarSubnetCount = + spec.forMilestone(specMilestone).miscHelpers().getBlobSidecarSubnetCount().orElseThrow(); assertThat( filter.isRelevantTopic( - getTopicName( - getBlobSidecarSubnetTopicName( - specConfigDeneb.getBlobSidecarSubnetCount() + 1)))) + getTopicName(getBlobSidecarSubnetTopicName(blobSidecarSubnetCount + 1)))) .isFalse(); } - @Test + @TestTemplate void shouldNotConsiderBlobSidecarWithoutIndexTopicRelevant() { assertThat(filter.isRelevantTopic(getTopicName("blob_sidecar"))).isFalse(); } - @Test + @TestTemplate void shouldNotAllowTopicsWithUnknownForkDigest() { final String irrelevantTopic = GossipTopics.getTopic(