diff --git a/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/ConnectionPriorityTest.java b/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/ConnectionPriorityTest.java index 032d7e12e2c3..642378629506 100644 --- a/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/ConnectionPriorityTest.java +++ b/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/ConnectionPriorityTest.java @@ -2,7 +2,6 @@ package org.hiero.otter.fixtures.internal; import static org.assertj.core.api.Assertions.assertThat; -import static org.hiero.otter.fixtures.internal.AbstractNetwork.BandwidthControlSupport.BANDWIDTH_CONTROL_SUPPORTED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -11,6 +10,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.Random; import org.assertj.core.data.Percentage; import org.hiero.consensus.model.node.KeysAndCerts; import org.hiero.consensus.model.node.NodeId; @@ -275,7 +275,7 @@ private static class TestableNetwork extends AbstractNetwork { private final ControllableTopology controllableTopology; TestableNetwork() { - super(new java.util.Random(42), false, BANDWIDTH_CONTROL_SUPPORTED); + super(new Random(42), false); this.controllableTopology = new ControllableTopology(super.topology()); } diff --git a/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/UnidirectionalConnectionImplTest.java b/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/UnidirectionalConnectionImplTest.java index 9744885c61fe..dd9f66f03c92 100644 --- a/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/UnidirectionalConnectionImplTest.java +++ b/platform-sdk/consensus-otter-tests/src/test/java/org/hiero/otter/fixtures/internal/UnidirectionalConnectionImplTest.java @@ -3,7 +3,6 @@ import static java.time.temporal.ChronoUnit.MILLIS; import static org.assertj.core.api.Assertions.assertThat; -import static org.hiero.otter.fixtures.internal.AbstractNetwork.BandwidthControlSupport.BANDWIDTH_CONTROL_SUPPORTED; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -12,6 +11,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import java.util.Random; import org.assertj.core.data.Percentage; import org.hiero.consensus.model.node.KeysAndCerts; import org.hiero.consensus.model.node.NodeId; @@ -223,7 +223,7 @@ void multipleConnectionObjectsReferSameUnderlyingConnection() { private static class TestableNetwork extends AbstractNetwork { TestableNetwork() { - super(new java.util.Random(42), false, BANDWIDTH_CONTROL_SUPPORTED); + super(new Random(42), false); } @Override diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/container/ContainerNetwork.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/container/ContainerNetwork.java index 2f25f3ca0fc8..28b881e7671e 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/container/ContainerNetwork.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/container/ContainerNetwork.java @@ -2,7 +2,6 @@ package org.hiero.otter.fixtures.container; import static java.util.Objects.requireNonNull; -import static org.hiero.otter.fixtures.internal.AbstractNetwork.BandwidthControlSupport.BANDWIDTH_CONTROL_SUPPORTED; import com.hedera.hapi.node.state.roster.Roster; import edu.umd.cs.findbugs.annotations.NonNull; @@ -74,7 +73,7 @@ public ContainerNetwork( final boolean proxyEnabled, final boolean gcLoggingEnabled, @NonNull final List jvmArgs) { - super(new Random(), useRandomNodeIds, BANDWIDTH_CONTROL_SUPPORTED); + super(new Random(), useRandomNodeIds); this.timeManager = requireNonNull(timeManager); this.transactionGenerator = requireNonNull(transactionGenerator); this.rootOutputDirectory = requireNonNull(rootOutputDirectory); diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNetwork.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNetwork.java index 38599e383ad0..34de4522ef60 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNetwork.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNetwork.java @@ -96,11 +96,6 @@ */ public abstract class AbstractNetwork implements Network { - public enum BandwidthControlSupport { - BANDWIDTH_CONTROL_SUPPORTED, - BANDWIDTH_CONTROL_NOT_SUPPORTED - } - /** * The fraction of nodes that must consider a node behind for the node to be considered behind by the network. */ @@ -129,7 +124,7 @@ protected enum Lifecycle { /** The default timeout duration for network operations. */ private static final Duration DEFAULT_TIMEOUT = Duration.ofMinutes(2L); - private final Random random; + protected final Random random; private final Map networkPartitions = new HashMap<>(); private final Map connected = new HashMap<>(); private final Map latencyOverrides = new HashMap<>(); @@ -139,8 +134,6 @@ protected enum Lifecycle { private Topology currentTopology; protected final NetworkConfiguration networkConfiguration; - private final boolean bandwidthControlNotSupported; - protected Lifecycle lifecycle = Lifecycle.INIT; protected WeightGenerator weightGenerator = WeightGenerators.REAL_NETWORK_GAUSSIAN; @@ -152,18 +145,13 @@ protected enum Lifecycle { private NodeId nextNodeId = NodeId.FIRST_NODE_ID; - protected AbstractNetwork( - @NonNull final Random random, - final boolean useRandomNodeIds, - @NonNull final BandwidthControlSupport bandwidthControlSupport) { + protected AbstractNetwork(@NonNull final Random random, final boolean useRandomNodeIds) { this.random = requireNonNull(random); this.useRandomNodeIds = useRandomNodeIds; // Initialize with default GeoMeshTopology this.currentTopology = new GeoMeshTopologyImpl( GeoMeshTopologyConfiguration.DEFAULT, random, this::createNodes, this::createInstrumentedNode); this.networkConfiguration = new NetworkConfiguration(); - this.bandwidthControlNotSupported = - bandwidthControlSupport != BandwidthControlSupport.BANDWIDTH_CONTROL_SUPPORTED; } /** @@ -613,9 +601,6 @@ private void setLatencyRange( */ @Override public void setBandwidthForAllConnections(@NonNull final Node node, @NonNull final BandwidthLimit bandwidthLimit) { - if (bandwidthControlNotSupported && !bandwidthLimit.isUnlimited()) { - throw new UnsupportedOperationException("Bandwidth control is not supported."); - } log.info("Setting bandwidth for all connections from node {} to {}", node.selfId(), bandwidthLimit); for (final Node otherNode : nodes()) { if (!node.equals(otherNode)) { @@ -1346,9 +1331,6 @@ public BandwidthLimit bandwidthLimit() { @Override public void bandwidthLimit(@NonNull final BandwidthLimit bandwidthLimit) { requireNonNull(bandwidthLimit); - if (bandwidthControlNotSupported && !bandwidthLimit.isUnlimited()) { - throw new UnsupportedOperationException("Bandwidth control is not supported."); - } log.info( "Setting bandwidth limit from node {} to node {} to {}", sender.selfId(), diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNode.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNode.java index e281c994c7bc..6f8cd4f65a8b 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNode.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/internal/AbstractNode.java @@ -97,7 +97,7 @@ protected AbstractNode( if (networkConfiguration.weight() != UNSET_WEIGHT) { weight(networkConfiguration.weight()); } - version(networkConfiguration.version()); + this.version = networkConfiguration.version(); final Path savedStateDirectory = networkConfiguration.savedStateDirectory(); if (savedStateDirectory != null) { startFromSavedState(savedStateDirectory); diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/InstrumentedTurtleNode.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/InstrumentedTurtleNode.java index d6f12f0a22ca..b69a9c75391a 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/InstrumentedTurtleNode.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/InstrumentedTurtleNode.java @@ -3,11 +3,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.nio.file.Path; +import java.util.Random; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hiero.consensus.model.node.KeysAndCerts; import org.hiero.consensus.model.node.NodeId; -import org.hiero.consensus.test.fixtures.Randotron; import org.hiero.otter.fixtures.InstrumentedNode; import org.hiero.otter.fixtures.internal.NetworkConfiguration; import org.hiero.otter.fixtures.internal.result.ConsensusRoundPool; @@ -24,7 +24,7 @@ public class InstrumentedTurtleNode extends TurtleNode implements InstrumentedNo /** * Constructor for the {@link InstrumentedTurtleNode} class. * - * @param randotron the random number generator + * @param random the random number generator * @param timeManager the time provider * @param selfId the node ID of the node * @param keysAndCerts the keys and certificates of the node @@ -35,7 +35,7 @@ public class InstrumentedTurtleNode extends TurtleNode implements InstrumentedNo * @param consensusRoundPool the shared pool for deduplicating consensus rounds */ public InstrumentedTurtleNode( - @NonNull final Randotron randotron, + @NonNull final Random random, @NonNull final TurtleTimeManager timeManager, @NonNull final NodeId selfId, @NonNull final KeysAndCerts keysAndCerts, @@ -45,7 +45,7 @@ public InstrumentedTurtleNode( @NonNull final NetworkConfiguration networkConfiguration, @NonNull final ConsensusRoundPool consensusRoundPool) { super( - randotron, + random, timeManager, selfId, keysAndCerts, diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/SecureRandomBuilder.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/SecureRandomBuilder.java index 80a889bf79b7..59fb062a55b0 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/SecureRandomBuilder.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/SecureRandomBuilder.java @@ -14,13 +14,6 @@ public class SecureRandomBuilder implements Supplier { private final Random seedSource; - /** - * Constructor. Random seed is used. - */ - public SecureRandomBuilder() { - seedSource = new Random(); - } - /** * Constructor. * diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNetwork.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNetwork.java index f998dfd3808e..49f2f4b3e108 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNetwork.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNetwork.java @@ -2,7 +2,6 @@ package org.hiero.otter.fixtures.turtle; import static java.util.Objects.requireNonNull; -import static org.hiero.otter.fixtures.internal.AbstractNetwork.BandwidthControlSupport.BANDWIDTH_CONTROL_NOT_SUPPORTED; import static org.junit.jupiter.api.Assertions.fail; import com.hedera.hapi.node.state.roster.Roster; @@ -12,6 +11,7 @@ import java.time.Duration; import java.time.Instant; import java.util.Map; +import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -20,7 +20,6 @@ import org.hiero.consensus.model.node.KeysAndCerts; import org.hiero.consensus.model.node.NodeId; import org.hiero.consensus.model.quiescence.QuiescenceCommand; -import org.hiero.consensus.test.fixtures.Randotron; import org.hiero.otter.fixtures.InstrumentedNode; import org.hiero.otter.fixtures.Network; import org.hiero.otter.fixtures.TimeManager; @@ -45,7 +44,6 @@ public class TurtleNetwork extends AbstractNetwork implements TimeTickReceiver { private static final Logger log = LogManager.getLogger(); - private final Randotron randotron; private final TurtleTimeManager timeManager; private final TurtleLogging logging; private final Path rootOutputDirectory; @@ -58,7 +56,7 @@ public class TurtleNetwork extends AbstractNetwork implements TimeTickReceiver { /** * Constructor for TurtleNetwork. * - * @param randotron the random generator + * @param random the random generator * @param timeManager the time manager * @param logging the logging utility * @param rootOutputDirectory the directory where the node output will be stored, like saved state and so on @@ -66,19 +64,18 @@ public class TurtleNetwork extends AbstractNetwork implements TimeTickReceiver { * @param useRandomNodeIds {@code true} if the node IDs should be selected randomly; {@code false} otherwise */ public TurtleNetwork( - @NonNull final Randotron randotron, + @NonNull final Random random, @NonNull final TurtleTimeManager timeManager, @NonNull final TurtleLogging logging, @NonNull final Path rootOutputDirectory, @NonNull final TurtleTransactionGenerator transactionGenerator, final boolean useRandomNodeIds) { - super(randotron, useRandomNodeIds, BANDWIDTH_CONTROL_NOT_SUPPORTED); - this.randotron = requireNonNull(randotron); + super(random, useRandomNodeIds); this.timeManager = requireNonNull(timeManager); this.logging = requireNonNull(logging); this.rootOutputDirectory = requireNonNull(rootOutputDirectory); this.transactionGenerator = requireNonNull(transactionGenerator); - this.simulatedNetwork = new SimulatedNetwork(randotron); + this.simulatedNetwork = new SimulatedNetwork(random); } /** @@ -104,6 +101,11 @@ protected TransactionGenerator transactionGenerator() { */ @Override protected void onConnectionsChanged(@NonNull final Map connections) { + final boolean limited = connections.values().stream() + .anyMatch(state -> !state.bandwidthLimit().isUnlimited()); + if (limited) { + throw new UnsupportedOperationException("Bandwidth limits are not supported in Turtle."); + } simulatedNetwork.setConnections(connections); } @@ -122,7 +124,7 @@ protected TurtleNode doCreateNode(@NonNull final NodeId nodeId, @NonNull final K simulatedNetwork.addNode(nodeId, simulatedGossip); final Path outputDir = rootOutputDirectory.resolve(NODE_IDENTIFIER_FORMAT.formatted(nodeId.id())); return new TurtleNode( - randotron, + random, timeManager, nodeId, keysAndCerts, @@ -144,7 +146,7 @@ protected InstrumentedNode doCreateInstrumentedNode( simulatedNetwork.addNode(nodeId, simulatedGossip); final Path outputDir = rootOutputDirectory.resolve(NODE_IDENTIFIER_FORMAT.formatted(nodeId.id())); return new InstrumentedTurtleNode( - randotron, + random, timeManager, nodeId, keysAndCerts, diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNode.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNode.java index 4cb3418bbfa1..5cb09b63c5c2 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNode.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNode.java @@ -57,7 +57,6 @@ import org.hiero.consensus.roster.RosterStateId; import org.hiero.consensus.roster.WritableRosterStore; import org.hiero.consensus.state.signed.ReservedSignedState; -import org.hiero.consensus.test.fixtures.Randotron; import org.hiero.consensus.wiring.framework.model.DeterministicWiringModel; import org.hiero.consensus.wiring.framework.model.WiringModelBuilder; import org.hiero.otter.fixtures.Node; @@ -101,7 +100,7 @@ public class TurtleNode extends AbstractNode implements Node, TurtleTimeManager. */ private static final Logger startupLogger = LogManager.getLogger("com.swirlds.platform.node.startup"); - private final Randotron randotron; + private final Random random; private final TurtleTimeManager timeManager; private final SimulatedGossip gossip; private final TurtleLogging logging; @@ -130,7 +129,7 @@ public class TurtleNode extends AbstractNode implements Node, TurtleTimeManager. /** * Constructor of {@link TurtleNode}. * - * @param randotron the random number generator + * @param random the random number generator * @param timeManager the time manager for this test * @param selfId the node ID of the node * @param keysAndCerts the keys and certificates of the node @@ -141,7 +140,7 @@ public class TurtleNode extends AbstractNode implements Node, TurtleTimeManager. * @param consensusRoundPool the shared pool for deduplicating consensus rounds */ public TurtleNode( - @NonNull final Randotron randotron, + @NonNull final Random random, @NonNull final TurtleTimeManager timeManager, @NonNull final NodeId selfId, @NonNull final KeysAndCerts keysAndCerts, @@ -155,7 +154,7 @@ public TurtleNode( this.outputDirectory = requireNonNull(outputDirectory); logging.addNodeLogging(selfId, outputDirectory); - this.randotron = requireNonNull(randotron); + this.random = requireNonNull(random); this.timeManager = requireNonNull(timeManager); this.gossip = requireNonNull(gossip); this.logging = requireNonNull(logging); @@ -262,8 +261,7 @@ protected void doStart(@NonNull final Duration timeout) { final RosterHistory rosterHistory = rosterStore.getRosterHistory(); final String eventStreamLoc = Long.toString(selfId.id()); - this.executionLayer = - new OtterExecutionLayer(new Random(randotron.nextLong()), metrics, timeManager.time()); + this.executionLayer = new OtterExecutionLayer(new Random(random.nextLong()), metrics, timeManager.time()); final TestPlatformBuilder builder = new TestPlatformBuilder( currentConfiguration, @@ -283,7 +281,7 @@ protected void doStart(@NonNull final Duration timeout) { eventStreamLoc, OtterApp.DEFAULT_TRANSACTION_OFFSET_NANOS) .withWiringModel(model) - .withSecureRandom(new SecureRandomBuilder(randotron.nextLong()).get()) + .withSecureRandom(new SecureRandomBuilder(random.nextLong()).get()) .withAdditionalProperties(Map.of("simulatedGossip", gossip)); platform = builder.build(); @@ -473,7 +471,7 @@ public SingleNodeEventStreamResult newEventStreamResult() { @Override @NonNull protected Random random() { - return randotron; + return random; } /** diff --git a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTransactionGenerator.java b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTransactionGenerator.java index 7cb72681e74d..40e16ea42dc6 100644 --- a/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTransactionGenerator.java +++ b/platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTransactionGenerator.java @@ -8,8 +8,8 @@ import java.time.Duration; import java.time.Instant; import java.util.List; +import java.util.Random; import org.hiero.consensus.model.status.PlatformStatus; -import org.hiero.consensus.test.fixtures.Randotron; import org.hiero.otter.fixtures.Node; import org.hiero.otter.fixtures.TransactionFactory; import org.hiero.otter.fixtures.TransactionGenerator; @@ -25,7 +25,7 @@ public class TurtleTransactionGenerator implements TransactionGenerator { private static final Duration CYCLE_DURATION = Duration.ofSeconds(1).dividedBy(TransactionGenerator.TPS); - private final Randotron randotron; + private final Random random; @Nullable private Instant startTime; @@ -38,10 +38,10 @@ public class TurtleTransactionGenerator implements TransactionGenerator { /** * Constructor for the {@link TurtleTransactionGenerator} class. * - * @param randotron the random number generator + * @param random the random number generator */ - public TurtleTransactionGenerator(@NonNull final Randotron randotron) { - this.randotron = requireNonNull(randotron); + public TurtleTransactionGenerator(@NonNull final Random random) { + this.random = requireNonNull(random); } /** @@ -86,8 +86,7 @@ public void tick(@NonNull final Instant now, @NonNull final List nodes) { for (long i = previousCount; i < currentCount; i++) { for (final Node node : activeNodes) { // Generate a random transaction and submit it to the node. - final OtterTransaction transaction = - TransactionFactory.createEmptyTransaction(randotron.nextLong()); + final OtterTransaction transaction = TransactionFactory.createEmptyTransaction(random.nextLong()); ((TurtleNode) node).submitTransaction(transaction); } }