diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/ConsensusOutput.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/ConsensusOutput.java index 35966f9bdb22..8445ffcfaf96 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/ConsensusOutput.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/ConsensusOutput.java @@ -4,7 +4,6 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; import java.util.Comparator; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -20,10 +19,10 @@ * Stores all output of consensus used in testing. This output can be used to validate consensus results. */ public class ConsensusOutput implements Clearable { - private final LinkedList consensusRounds; - private final LinkedList preConsensusEvents; - private final LinkedList addedEvents; - private final LinkedList staleEvents; + private final List consensusRounds; + private final List preConsensusEvents; + private final List addedEvents; + private final List staleEvents; private EventWindow eventWindow; @@ -31,10 +30,10 @@ public class ConsensusOutput implements Clearable { * Creates a new instance. */ public ConsensusOutput() { - addedEvents = new LinkedList<>(); - preConsensusEvents = new LinkedList<>(); - consensusRounds = new LinkedList<>(); - staleEvents = new LinkedList<>(); + addedEvents = new ArrayList<>(); + preConsensusEvents = new ArrayList<>(); + consensusRounds = new ArrayList<>(); + staleEvents = new ArrayList<>(); eventWindow = EventWindow.getGenesisEventWindow(); } @@ -60,9 +59,9 @@ public void consensusRound(@NonNull final ConsensusRound consensusRound) { } /** - * @return a queue of all events that have been marked as stale + * @return a list of all events that have been marked as stale */ - public @NonNull LinkedList getStaleEvents() { + public @NonNull List getStaleEvents() { return staleEvents; } @@ -76,9 +75,9 @@ public void consensusRound(@NonNull final ConsensusRound consensusRound) { } /** - * @return a queue of all rounds that have reached consensus + * @return a list of all rounds that have reached consensus */ - public @NonNull LinkedList getConsensusRounds() { + public @NonNull List getConsensusRounds() { return consensusRounds; } @@ -92,7 +91,7 @@ public void consensusRound(@NonNull final ConsensusRound consensusRound) { return consensusRounds.getLast(); } - public @NonNull LinkedList getAddedEvents() { + public @NonNull List getAddedEvents() { return addedEvents; } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/GenerateConsensus.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/GenerateConsensus.java index 3ab2fdc3eec9..222938a12c7b 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/GenerateConsensus.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/GenerateConsensus.java @@ -6,7 +6,6 @@ import com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.ArrayList; -import java.util.Deque; import java.util.List; import java.util.stream.IntStream; import org.hiero.consensus.hashgraph.impl.test.fixtures.event.generator.StandardGraphGenerator; @@ -31,7 +30,7 @@ private GenerateConsensus() {} * @param seed the seed to use * @return consensus rounds */ - public static Deque generateConsensusRounds( + public static List generateConsensusRounds( @NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time, diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/TestIntake.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/TestIntake.java index d6183b4d0daf..931ac12f8fe9 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/TestIntake.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/TestIntake.java @@ -165,9 +165,9 @@ public void addEvent(@NonNull final PlatformEvent event) { } /** - * @return a queue of all rounds that have reached consensus + * @return a list of all rounds that have reached consensus */ - public @NonNull LinkedList getConsensusRounds() { + public @NonNull List getConsensusRounds() { return output.getConsensusRounds(); } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/ConsensusTestNode.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/ConsensusTestNode.java index dcb299cfc6cb..82cd2ce3e55f 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/ConsensusTestNode.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/ConsensusTestNode.java @@ -8,8 +8,8 @@ import com.swirlds.config.api.Configuration; import com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.LinkedList; -import java.util.Objects; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import org.hiero.consensus.hashgraph.impl.test.fixtures.consensus.ConsensusOutput; import org.hiero.consensus.hashgraph.impl.test.fixtures.consensus.TestIntake; @@ -65,9 +65,8 @@ public ConsensusTestNode(@NonNull final EventEmitter eventEmitter, @NonNull fina public void restart() { // clear all generators eventEmitter.reset(); - final ConsensusSnapshot snapshot = Objects.requireNonNull( - getOutput().getConsensusRounds().peekLast()) - .getSnapshot(); + final ConsensusSnapshot snapshot = + getOutput().getConsensusRounds().getLast().getSnapshot(); intake.reset(); intake.loadSnapshot(snapshot); } @@ -78,13 +77,12 @@ public void restart() { */ public void removeNode(@NonNull final NodeId nodeId) { eventEmitter.getGraphGenerator().removeNode(nodeId); - final ConsensusSnapshot snapshot = Objects.requireNonNull( - getOutput().getConsensusRounds().peekLast()) - .getSnapshot(); + final ConsensusSnapshot snapshot = + getOutput().getConsensusRounds().getLast().getSnapshot(); intake.loadSnapshot(snapshot); // the above will clear all events from the linker and consensus, so we need to add all non-ancient events // adding events will also add the events to the output, so we make a copy of the list and add them back - final LinkedList added = new LinkedList<>(getOutput().getAddedEvents()); + final List added = new ArrayList<>(getOutput().getAddedEvents()); getOutput().getAddedEvents().clear(); for (final PlatformEvent e : added) { intake.addEvent(e.copyGossipedData()); @@ -113,8 +111,7 @@ public void removeNode(@NonNull final NodeId nodeId) { time, newEmitter.getGraphGenerator().getRoster())); consensusTestNode.intake.loadSnapshot( - Objects.requireNonNull(getOutput().getConsensusRounds().peekLast()) - .getSnapshot()); + getOutput().getConsensusRounds().getLast().getSnapshot()); assertThat(consensusTestNode.intake.getConsensusRounds()) .withFailMessage("we should not have reached consensus yet") diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/ConsensusRoundValidator.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/ConsensusRoundValidator.java index 2da7b3127015..d85eab81dd55 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/ConsensusRoundValidator.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/ConsensusRoundValidator.java @@ -34,7 +34,7 @@ private ConsensusRoundValidator() {} public static void validate( @NonNull final List rounds1, @NonNull final List rounds2) { assertThat(rounds1) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "The number of consensus rounds is not the same." + "first argument has %d rounds, second has %d rounds", rounds1.size(), rounds2.size())) diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/NumberOfConsensusRoundsValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/NumberOfConsensusRoundsValidation.java index a81e95be8089..00a82dc47b5b 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/NumberOfConsensusRoundsValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/NumberOfConsensusRoundsValidation.java @@ -14,10 +14,10 @@ public record NumberOfConsensusRoundsValidation(int numberOfRounds) implements C @Override public void validate(@NonNull final ConsensusOutput output1, @NonNull final ConsensusOutput output2) { for (final ConsensusOutput output : List.of(output1, output2)) { - Assertions.assertThat(output.getConsensusRounds().size()) + final int actualRounds = output.getConsensusRounds().size(); + Assertions.assertThat(actualRounds) .withFailMessage( - "Expected %d rounds, but got %d", - numberOfRounds, output.getConsensusRounds().size()) + () -> String.format("Expected %d rounds, but got %d", numberOfRounds, actualRounds)) .isEqualTo(numberOfRounds); } } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputEventRatioValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputEventRatioValidation.java index 8c1f668a5350..7718a5f5c79d 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputEventRatioValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputEventRatioValidation.java @@ -101,12 +101,12 @@ public void validate(@NonNull final ConsensusOutput output1, @NonNull final Cons final double consensusRatio = ((double) numConsensus) / allEvents1.size(); assertThat(consensusRatio) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "Consensus ratio %s is less than the expected minimum %s", consensusRatio, minimumConsensusRatio)) .isGreaterThanOrEqualTo(minimumConsensusRatio); assertThat(consensusRatio) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "Consensus ratio %s is more than the expected maximum %s", consensusRatio, maximumConsensusRatio)) .isLessThanOrEqualTo(maximumConsensusRatio); @@ -115,11 +115,11 @@ public void validate(@NonNull final ConsensusOutput output1, @NonNull final Cons final double staleRatio = ((double) output1.getStaleEvents().size()) / allEvents1.size(); assertThat(staleRatio) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "Stale ratio %s is less than the expected minimum %s", staleRatio, minimumStaleRatio)) .isGreaterThanOrEqualTo(minimumStaleRatio); assertThat(staleRatio) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "Stale ratio %s is more than the expected maximum %s", staleRatio, maximumStaleRatio)) .isLessThanOrEqualTo(maximumStaleRatio); } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputNoEventsLostValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputNoEventsLostValidation.java index f0613e7a1107..25b8ff88990b 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputNoEventsLostValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/OutputNoEventsLostValidation.java @@ -5,6 +5,7 @@ import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.hiero.base.crypto.Hash; @@ -12,6 +13,7 @@ import org.hiero.consensus.hashgraph.config.ConsensusConfig; import org.hiero.consensus.hashgraph.impl.test.fixtures.consensus.ConsensusOutput; import org.hiero.consensus.model.event.PlatformEvent; +import org.hiero.consensus.model.hashgraph.ConsensusRound; import org.hiero.consensus.round.RoundCalculationUtils; @SuppressWarnings("unused") // issue tracked #6998 @@ -29,31 +31,33 @@ private OutputNoEventsLostValidation() {} * neither, so they are not checked. */ public void validate(@NonNull final ConsensusOutput output, @NonNull final ConsensusOutput ignored) { + final List consensusRounds = output.getConsensusRounds(); + if (consensusRounds.isEmpty()) { + // no consensus reached, nothing to check + return; + } + final Map stale = output.getStaleEvents().stream().collect(Collectors.toMap(Hashable::getHash, e -> e)); - final Map cons = output.getConsensusRounds().stream() + final Map cons = consensusRounds.stream() .flatMap(r -> r.getConsensusEvents().stream()) .collect(Collectors.toMap(PlatformEvent::getHash, e -> e)); - if (output.getConsensusRounds().isEmpty()) { - // no consensus reached, nothing to check - return; - } final long nonAncientThreshold = RoundCalculationUtils.getAncientThreshold( - CONFIG.roundsNonAncient(), output.getConsensusRounds().getLast().getSnapshot()); + CONFIG.roundsNonAncient(), consensusRounds.getLast().getSnapshot()); for (final PlatformEvent event : output.getAddedEvents()) { if (event.getBirthRound() >= nonAncientThreshold) { // non-ancient events are not checked continue; } - if (stale.containsKey(event.getHash()) == cons.containsKey(event.getHash())) { + final Hash hash = event.getHash(); + final boolean isStale = stale.containsKey(hash); + final boolean isConsensus = cons.containsKey(hash); + if (isStale == isConsensus) { fail(String.format( "An ancient event should be either stale or consensus, but not both!\n" + "nonAncientGen=%d, Event %s, stale=%s, consensus=%s", - nonAncientThreshold, - event.getDescriptor(), - stale.containsKey(event.getHash()), - cons.containsKey(event.getHash()))); + nonAncientThreshold, event.getDescriptor(), isStale, isConsensus)); } } } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundAncientThresholdIncreasesValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundAncientThresholdIncreasesValidation.java index 9570f31b171d..9168e9b8e923 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundAncientThresholdIncreasesValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundAncientThresholdIncreasesValidation.java @@ -26,16 +26,20 @@ public void validate(@NonNull final List rounds) { return; } - for (int i = 1; i < rounds.size(); i++) { + // Carry the previous round's threshold across iterations so each round's snapshot chain is + // resolved only once instead of once as "current" and again as "previous". + MinimumJudgeInfo previousThresholdInfo = + rounds.getFirst().getSnapshot().minimumJudgeInfoList().getLast(); + for (int i = 1, n = rounds.size(); i < n; i++) { - final MinimumJudgeInfo previousThresholdInfo = - rounds.get(i - 1).getSnapshot().minimumJudgeInfoList().getLast(); final MinimumJudgeInfo currentThresholdInfo = rounds.get(i).getSnapshot().minimumJudgeInfoList().getLast(); assertThat(currentThresholdInfo.minimumJudgeBirthRound()) .withFailMessage("the ancient threshold should never decrease") .isGreaterThanOrEqualTo(previousThresholdInfo.minimumJudgeBirthRound()); + + previousThresholdInfo = currentThresholdInfo; } } } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalConsistencyValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalConsistencyValidation.java index 9eebbe746e90..b1dafaae89b8 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalConsistencyValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalConsistencyValidation.java @@ -24,7 +24,7 @@ public void validate(@NonNull final List rounds) { final MinimumJudgeInfo minimumJudgeInfo = round.getSnapshot().minimumJudgeInfoList().getLast(); assertThat(round.getRoundNum()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "the last threshold should be equal for the current round %d", round.getRoundNum())) .isEqualTo(minimumJudgeInfo.round()); diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalEqualityValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalEqualityValidation.java index 85dc09e3f0e2..48cc101bfd3e 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalEqualityValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundInternalEqualityValidation.java @@ -6,6 +6,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Iterator; import java.util.Objects; +import java.util.function.Supplier; import org.hiero.consensus.model.event.PlatformEvent; import org.hiero.consensus.model.hashgraph.ConsensusRound; @@ -26,15 +27,15 @@ public void validate(@NonNull final ConsensusRound round1, @NonNull final Consen final long firstRoundNumber = round1.getRoundNum(); final long secondRoundNumber = round2.getRoundNum(); assertThat(round1.getRoundNum()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "round diff at rounds with numbers %d and %d", firstRoundNumber, secondRoundNumber)) .isEqualTo(round2.getRoundNum()); assertThat(round1.getEventCount()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "event number diff at rounds with numbers %d and %d", firstRoundNumber, secondRoundNumber)) .isEqualTo(round2.getEventCount()); assertThat(round1.getSnapshot()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "snapshot diff at rounds with numbers %d and %d", firstRoundNumber, secondRoundNumber)) .isEqualTo(round2.getSnapshot()); final Iterator evIt1 = round1.getConsensusEvents().iterator(); @@ -43,20 +44,21 @@ public void validate(@NonNull final ConsensusRound round1, @NonNull final Consen while (evIt1.hasNext() && evIt2.hasNext()) { final PlatformEvent e1 = evIt1.next(); final PlatformEvent e2 = evIt2.next(); + final int index = eventIndex; assertThat(e1.getConsensusData()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "output:1, roundNumberFromFirstNode:%d, roundNumberFromSecondRound:%d, eventIndex%d is not consensus", - firstRoundNumber, secondRoundNumber, eventIndex)) + firstRoundNumber, secondRoundNumber, index)) .isNotNull(); assertThat(e2.getConsensusData()) - .withFailMessage(String.format( + .withFailMessage(() -> String.format( "output:1, roundNumberFromFirstNode:%d, roundNumberFromSecondRound:%d, eventIndex%d is not consensus", - firstRoundNumber, secondRoundNumber, eventIndex)) + firstRoundNumber, secondRoundNumber, index)) .isNotNull(); assertConsensusEvents( - String.format( + () -> String.format( "roundNumberFromFirstNode:%d, roundNumberFromSecondRound:%d, event index %d", - firstRoundNumber, secondRoundNumber, eventIndex), + firstRoundNumber, secondRoundNumber, index), e1, e2); eventIndex++; @@ -67,16 +69,16 @@ public void validate(@NonNull final ConsensusRound round1, @NonNull final Consen * Assert that two events are equal. If they are not equal then cause the test to fail and print * a meaningful error message. * - * @param description a string that is printed if the events are unequal + * @param description supplies a string that is printed if the events are unequal; only evaluated on failure * @param e1 the first event * @param e2 the second event */ private static void assertConsensusEvents( - final String description, final PlatformEvent e1, final PlatformEvent e2) { + final Supplier description, final PlatformEvent e1, final PlatformEvent e2) { final boolean equal = Objects.equals(e1, e2); if (!equal) { final StringBuilder sb = new StringBuilder(); - sb.append(description).append("\n"); + sb.append(description.get()).append("\n"); sb.append("Events are not equal:\n"); sb.append("Event 1: ").append(e1).append("\n"); sb.append("Event 2: ").append(e2).append("\n"); diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundTimestampCheckerValidation.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundTimestampCheckerValidation.java index 06442af0ab33..8d08797c6c84 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundTimestampCheckerValidation.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/RoundTimestampCheckerValidation.java @@ -23,39 +23,48 @@ public enum RoundTimestampCheckerValidation implements ConsensusRoundConsistency @Override public void validate(@NonNull final List rounds) { for (final ConsensusRound round : rounds) { - for (int i = 1; i < round.getEventCount(); i++) { + final List events = round.getConsensusEvents(); + for (int i = 1, n = events.size(); i < n; i++) { - final PlatformEvent previousEvent = round.getConsensusEvents().get(i - 1); - final PlatformEvent currentEvent = round.getConsensusEvents().get(i); + final PlatformEvent previousEvent = events.get(i - 1); + final PlatformEvent currentEvent = events.get(i); // Check the consensus timestamp assertThat(currentEvent.getConsensusTimestamp()) - .withFailMessage(String.format( - "Consensus time does not increase!%n" - + "Event %s consOrder:%s consTime:%s%n" - + "Event %s consOrder:%s consTime:%s%n", - previousEvent.getDescriptor(), - previousEvent.getConsensusOrder(), - previousEvent.getConsensusTimestamp(), - currentEvent.getDescriptor(), - currentEvent.getConsensusOrder(), - currentEvent.getConsensusTimestamp())) + .withFailMessage( + () -> failMessage("Consensus time does not increase!", previousEvent, currentEvent)) .isAfter(previousEvent.getConsensusTimestamp()); // Check the consensus order assertThat(currentEvent.getConsensusOrder()) - .withFailMessage(String.format( - "Consensus order does not increase by 1!%n" - + "Event %s consOrder:%s consTime:%s%n" - + "Event %s consOrder:%s consTime:%s%n", - previousEvent.getDescriptor(), - previousEvent.getConsensusOrder(), - previousEvent.getConsensusTimestamp(), - currentEvent.getDescriptor(), - currentEvent.getConsensusOrder(), - currentEvent.getConsensusTimestamp())) + .withFailMessage(() -> + failMessage("Consensus order does not increase by 1!", previousEvent, currentEvent)) .isEqualTo(previousEvent.getConsensusOrder() + 1); } } } + + /** + * Renders the failure message for a pair of adjacent events. + * + * @param headline describes which of the two checks failed + * @param previousEvent the earlier of the two events + * @param currentEvent the latter of the two events + * @return the failure message + */ + @NonNull + private static String failMessage( + @NonNull final String headline, + @NonNull final PlatformEvent previousEvent, + @NonNull final PlatformEvent currentEvent) { + return String.format( + "%s%nEvent %s consOrder:%s consTime:%s%nEvent %s consOrder:%s consTime:%s%n", + headline, + previousEvent.getDescriptor(), + previousEvent.getConsensusOrder(), + previousEvent.getConsensusTimestamp(), + currentEvent.getDescriptor(), + currentEvent.getConsensusOrder(), + currentEvent.getConsensusTimestamp()); + } } diff --git a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/TestFixtureValidationUtils.java b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/TestFixtureValidationUtils.java index daf94aa38736..324a5cc57b47 100644 --- a/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/TestFixtureValidationUtils.java +++ b/platform-sdk/consensus-hashgraph-impl/src/testFixtures/java/org/hiero/consensus/hashgraph/impl/test/fixtures/consensus/framework/validation/TestFixtureValidationUtils.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.fail; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Iterator; import java.util.List; import org.hiero.consensus.model.event.PlatformEvent; @@ -28,9 +29,14 @@ static void assertBaseEventLists( fail(String.format("Length of event lists are unequal: %d vs %d", l1.size(), l2.size())); } - for (int index = 0; index < l1.size(); index++) { - final PlatformEvent e1 = l1.get(index); - final PlatformEvent e2 = l2.get(index); + // Iterate rather than index into the lists: the arguments may be linked lists, for which + // repeated get(index) calls would make this loop quadratic. + final Iterator it1 = l1.iterator(); + final Iterator it2 = l2.iterator(); + int index = 0; + while (it1.hasNext() && it2.hasNext()) { + final PlatformEvent e1 = it1.next(); + final PlatformEvent e2 = it2.next(); final boolean equals = e1.equalsGossipedData(e2); if (shouldBeEqual && !equals) { final String sb = description @@ -50,6 +56,7 @@ static void assertBaseEventLists( // events are not equal, and they are not expected to be, we can stop checking return; } + index++; } if (!shouldBeEqual) { // events are not expected to be equal, but we have gone through the whole list without finding a mismatch diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/MultipleNodeLogResultsContinuousAssert.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/MultipleNodeLogResultsContinuousAssert.java index 40919e132ab4..28b1349138bf 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/MultipleNodeLogResultsContinuousAssert.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/MultipleNodeLogResultsContinuousAssert.java @@ -13,6 +13,7 @@ import java.util.function.Consumer; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; +import org.hiero.consensus.model.node.NodeId; import org.hiero.otter.fixtures.logging.StructuredLog; import org.hiero.otter.fixtures.result.LogSubscriber; import org.hiero.otter.fixtures.result.MultipleNodeLogResults; @@ -104,8 +105,9 @@ public MultipleNodeLogResultsContinuousAssert haveNoMessageWithMarkers( */ @NonNull public MultipleNodeLogResultsContinuousAssert haveNoMessageWithLevelHigherThan(@NonNull final Level level) { + final int thresholdIntLevel = level.intLevel(); return checkContinuously(logEntry -> { - if (logEntry.level().intLevel() < level.intLevel()) { + if (logEntry.level().intLevel() < thresholdIntLevel) { failWithMessage( "Expected no message with level higher than %s, but found %s in %n%s", level, logEntry.level(), logEntry); @@ -143,8 +145,10 @@ private MultipleNodeLogResultsContinuousAssert checkContinuously(final Consumer< final LogSubscriber subscriber = logEntry -> switch (state) { case ACTIVE -> { - if ((logEntry.nodeId() == null || !suppressedNodeIds.contains(logEntry.nodeId())) - && (logEntry.marker() == null || !suppressedLogMarkers.contains(logEntry.marker()))) { + final NodeId nodeId = logEntry.nodeId(); + final Marker marker = logEntry.marker(); + if ((nodeId == null || !suppressedNodeIds.contains(nodeId)) + && (marker == null || !suppressedLogMarkers.contains(marker))) { check.accept(logEntry); } yield CONTINUE; diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/SingleNodeLogResultContinuousAssert.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/SingleNodeLogResultContinuousAssert.java index 06a406e6e109..8b25acd58c5c 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/SingleNodeLogResultContinuousAssert.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/assertions/SingleNodeLogResultContinuousAssert.java @@ -103,8 +103,9 @@ public SingleNodeLogResultContinuousAssert haveNoMessageWithMarkers( */ @NonNull public SingleNodeLogResultContinuousAssert haveNoMessageWithLevelHigherThan(@NonNull final Level level) { + final int thresholdIntLevel = level.intLevel(); return checkContinuously(logEntry -> { - if (logEntry.level().intLevel() < level.intLevel()) { + if (logEntry.level().intLevel() < thresholdIntLevel) { failWithMessage( "Expected no message with level higher than %s, but found %s in %n%s", level, logEntry.level(), logEntry); @@ -142,7 +143,8 @@ private SingleNodeLogResultContinuousAssert checkContinuously(final Consumer switch (state) { case ACTIVE -> { - if (logEntry.marker() == null || !suppressedLogMarkers.contains(logEntry.marker())) { + final Marker marker = logEntry.marker(); + if (marker == null || !suppressedLogMarkers.contains(marker)) { check.accept(logEntry); } yield CONTINUE; diff --git a/platform-sdk/swirlds-cli/src/test/java/org/hiero/consensus/pcli/report/EventStreamReportingToolTest.java b/platform-sdk/swirlds-cli/src/test/java/org/hiero/consensus/pcli/report/EventStreamReportingToolTest.java index 953d4d28c2e5..6fc0a7708af0 100644 --- a/platform-sdk/swirlds-cli/src/test/java/org/hiero/consensus/pcli/report/EventStreamReportingToolTest.java +++ b/platform-sdk/swirlds-cli/src/test/java/org/hiero/consensus/pcli/report/EventStreamReportingToolTest.java @@ -11,9 +11,7 @@ import java.nio.file.Path; import java.time.Duration; import java.time.Instant; -import java.util.Deque; import java.util.List; -import java.util.Optional; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; import org.hiero.base.constructable.ConstructableRegistryException; @@ -56,7 +54,7 @@ void createReportTest() throws IOException { final Duration eventStreamWindowSize = Duration.ofSeconds(1); // generate consensus events - final Deque rounds = GenerateConsensus.generateConsensusRounds( + final List rounds = GenerateConsensus.generateConsensusRounds( DEFAULT_CONFIGURATION, DEFAULT_METRICS, DEFAULT_TIME, numNodes, numEvents, random.nextLong()); if (rounds.isEmpty()) { Assertions.fail("events are excepted to reach consensus"); @@ -67,8 +65,7 @@ void createReportTest() throws IOException { .filter(r -> r.getRoundNum() >= roundToReportFrom) .mapToInt(ConsensusRound::getNumEvents) .sum(); - final List lastRound = - Optional.ofNullable(rounds.peekLast()).orElseThrow().getConsensusEvents(); + final List lastRound = rounds.getLast().getConsensusEvents(); final Instant lastEventTime = lastRound.get(lastRound.size() - 1).getConsensusTimestamp(); // write event stream @@ -98,7 +95,7 @@ void createTimeBoundReportTest() throws IOException { final Duration eventStreamWindowSize = Duration.ofSeconds(1); // generate consensus events - final Deque rounds = GenerateConsensus.generateConsensusRounds( + final List rounds = GenerateConsensus.generateConsensusRounds( DEFAULT_CONFIGURATION, DEFAULT_METRICS, DEFAULT_TIME, numNodes, numEvents, random.nextLong()); if (rounds.isEmpty()) { Assertions.fail("events are excepted to reach consensus"); @@ -117,8 +114,7 @@ void createTimeBoundReportTest() throws IOException { }) .mapToInt(ConsensusRound::getNumEvents) .sum(); - final List lastRound = - Optional.ofNullable(rounds.peekLast()).orElseThrow().getConsensusEvents(); + final List lastRound = rounds.getLast().getConsensusEvents(); final Instant lastEventTime = lastRound.get(lastRound.size() - 1).getConsensusTimestamp(); // write event stream