Skip to content

Commit 06499a9

Browse files
authored
chore: Cleanup of TurtleApp (#18952)
Signed-off-by: Michael Heinrichs <[email protected]>
1 parent db8dd4b commit 06499a9

File tree

11 files changed

+289
-96
lines changed

11 files changed

+289
-96
lines changed

platform-sdk/consensus-otter-tests/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ plugins {
1616
id("org.hiero.gradle.feature.test")
1717
id("org.hiero.gradle.report.test-logger")
1818
id("org.hiero.gradle.feature.test-fixtures")
19+
id("org.hiero.gradle.feature.protobuf")
1920
}
2021

2122
description = "Consensus Otter Test Framework"

platform-sdk/consensus-otter-tests/src/testFixtures/java/module-info.java

+2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
requires transitive com.swirlds.logging;
44
requires transitive com.swirlds.platform.core.test.fixtures;
55
requires transitive com.swirlds.platform.core;
6+
requires transitive com.google.protobuf;
67
requires transitive org.apache.logging.log4j.core;
78
requires transitive org.junit.jupiter.api;
9+
requires com.hedera.node.app.hapi.utils;
810
requires com.hedera.node.config;
911
requires com.hedera.node.hapi;
1012
requires com.hedera.pbj.runtime;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
package org.hiero.otter.fixtures.turtle;
3+
4+
import com.google.protobuf.ByteString;
5+
import com.hedera.hapi.platform.event.StateSignatureTransaction;
6+
import com.hedera.node.app.hapi.utils.CommonPbjConverters;
7+
import com.hederahashgraph.api.proto.java.Timestamp;
8+
import edu.umd.cs.findbugs.annotations.NonNull;
9+
import java.time.Instant;
10+
import org.hiero.base.utility.CommonUtils;
11+
import org.hiero.otter.fixtures.turtle.app.EmptyTransaction;
12+
import org.hiero.otter.fixtures.turtle.app.TurtleFreezeTransaction;
13+
import org.hiero.otter.fixtures.turtle.app.TurtleTransaction;
14+
15+
/**
16+
* Utility class for transaction-related operations.
17+
*/
18+
public class TransactionFactory {
19+
20+
private TransactionFactory() {}
21+
22+
/**
23+
* Creates a new empty transaction.
24+
*
25+
* @return an empty transaction
26+
*/
27+
public static TurtleTransaction createEmptyTransaction(final int nonce) {
28+
final EmptyTransaction emptyTransaction = EmptyTransaction.newBuilder().build();
29+
return TurtleTransaction.newBuilder()
30+
.setEmptyTransaction(emptyTransaction)
31+
.build();
32+
}
33+
34+
/**
35+
* Creates a freeze transaction with the specified freeze time.
36+
*
37+
* @param freezeTime the freeze time for the transaction
38+
* @return a FreezeTransaction with the provided freeze time
39+
*/
40+
public static TurtleTransaction createFreezeTransaction(@NonNull final Instant freezeTime) {
41+
final Timestamp timestamp = CommonPbjConverters.fromPbj(CommonUtils.toPbjTimestamp(freezeTime));
42+
final TurtleFreezeTransaction freezeTransaction =
43+
TurtleFreezeTransaction.newBuilder().setFreezeTime(timestamp).build();
44+
return TurtleTransaction.newBuilder()
45+
.setFreezeTransaction(freezeTransaction)
46+
.build();
47+
}
48+
49+
/**
50+
* Creates a transaction with the specified inner StateSignatureTransaction.
51+
*
52+
* @param innerTxn the StateSignatureTransaction
53+
* @return a TurtleTransaction with the specified inner transaction
54+
*/
55+
public static TurtleTransaction createStateSignatureTransaction(@NonNull final StateSignatureTransaction innerTxn) {
56+
final com.hedera.hapi.platform.event.legacy.StateSignatureTransaction legacyInnerTxn =
57+
com.hedera.hapi.platform.event.legacy.StateSignatureTransaction.newBuilder()
58+
.setRound(innerTxn.round())
59+
.setSignature(ByteString.copyFrom(innerTxn.signature().toByteArray()))
60+
.setHash(ByteString.copyFrom(innerTxn.hash().toByteArray()))
61+
.build();
62+
return TurtleTransaction.newBuilder()
63+
.setStateSignatureTransaction(legacyInnerTxn)
64+
.build();
65+
}
66+
}

platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleApp.java

-82
This file was deleted.

platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNetwork.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import static org.hiero.otter.fixtures.turtle.TurtleTestEnvironment.AVERAGE_NETWORK_DELAY;
99
import static org.hiero.otter.fixtures.turtle.TurtleTestEnvironment.STANDARD_DEVIATION_NETWORK_DELAY;
1010

11-
import com.hedera.pbj.runtime.io.buffer.Bytes;
1211
import com.swirlds.common.test.fixtures.Randotron;
1312
import com.swirlds.platform.crypto.KeysAndCerts;
1413
import com.swirlds.platform.system.address.AddressBook;
@@ -31,10 +30,12 @@
3130
import org.hiero.otter.fixtures.InstrumentedNode;
3231
import org.hiero.otter.fixtures.Network;
3332
import org.hiero.otter.fixtures.Node;
33+
import org.hiero.otter.fixtures.turtle.app.TurtleTransaction;
3434

3535
/**
3636
* An implementation of {@link Network} that is based on the Turtle framework.
3737
*/
38+
@SuppressWarnings("removal")
3839
public class TurtleNetwork implements Network, TurtleTimeManager.TimeTickReceiver {
3940

4041
private static final Logger log = LogManager.getLogger(TurtleNetwork.class);
@@ -62,15 +63,11 @@ private enum State {
6263
* @param randotron the random generator
6364
* @param timeManager the time manager
6465
* @param rootOutputDirectory the directory where the node output will be stored, like saved state and so on
65-
* @param averageNetworkDelay the average network delay
66-
* @param standardDeviationNetworkDelay the standard deviation of the network delay
6766
*/
6867
public TurtleNetwork(
6968
@NonNull final Randotron randotron,
7069
@NonNull final TurtleTimeManager timeManager,
71-
@NonNull final Path rootOutputDirectory,
72-
@NonNull final Duration averageNetworkDelay,
73-
@NonNull final Duration standardDeviationNetworkDelay) {
70+
@NonNull final Path rootOutputDirectory) {
7471
this.randotron = requireNonNull(randotron);
7572
this.timeManager = requireNonNull(timeManager);
7673
this.rootOutputDirectory = requireNonNull(rootOutputDirectory);
@@ -167,8 +164,10 @@ public void prepareUpgrade(@NonNull Duration timeout) throws InterruptedExceptio
167164
}
168165
log.info("Preparing upgrade...");
169166

170-
log.debug("Sending FREEZE transaction...");
171-
nodes.getFirst().submitTransaction(Bytes.wrap("FREEZE").toByteArray());
167+
log.debug("Sending TurtleFreezeTransaction transaction...");
168+
final TurtleTransaction freezeTransaction =
169+
TransactionFactory.createFreezeTransaction(timeManager.time().now());
170+
nodes.getFirst().submitTransaction(freezeTransaction.toByteArray());
172171

173172
log.debug("Waiting for nodes to freeze...");
174173
if (!timeManager.waitForCondition(allNodesInStatus(FREEZE_COMPLETE), timeout)) {

platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleNode.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.hiero.otter.fixtures.turtle.TurtleTestEnvironment.SWIRLD_NAME;
1111

1212
import com.hedera.hapi.node.base.SemanticVersion;
13+
import com.hedera.pbj.runtime.io.buffer.Bytes;
1314
import com.swirlds.base.time.Time;
1415
import com.swirlds.common.context.PlatformContext;
1516
import com.swirlds.common.io.config.FileSystemManagerConfig_;
@@ -54,6 +55,7 @@
5455
import org.hiero.consensus.model.status.PlatformStatus;
5556
import org.hiero.otter.fixtures.Node;
5657
import org.hiero.otter.fixtures.NodeConfiguration;
58+
import org.hiero.otter.fixtures.turtle.app.TurtleApp;
5759

5860
/**
5961
* A node in the turtle network.
@@ -337,7 +339,8 @@ private void doStartNode() {
337339
.withKeysAndCerts(privateKeys)
338340
.withPlatformContext(platformContext)
339341
.withConfiguration(currentConfiguration)
340-
.withSystemTransactionEncoderCallback(TurtleApp::encodeSystemTransaction);
342+
.withSystemTransactionEncoderCallback(txn -> Bytes.wrap(
343+
TransactionFactory.createStateSignatureTransaction(txn).toByteArray()));
341344

342345
final PlatformComponentBuilder platformComponentBuilder = platformBuilder.buildComponentBuilder();
343346
final PlatformBuildingBlocks platformBuildingBlocks = platformComponentBuilder.getBuildingBlocks();

platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTestEnvironment.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,12 @@ public TurtleTestEnvironment() {
9797
FileUtils.deleteDirectory(rootOutputDirectory);
9898
}
9999
} catch (IOException ex) {
100-
log.warn("Failed to delete directory: " + rootOutputDirectory, ex);
100+
log.warn("Failed to delete directory: {}", rootOutputDirectory, ex);
101101
}
102102

103103
timeManager = new TurtleTimeManager(time, GRANULARITY);
104104

105-
network = new TurtleNetwork(
106-
randotron, timeManager, rootOutputDirectory, AVERAGE_NETWORK_DELAY, STANDARD_DEVIATION_NETWORK_DELAY);
105+
network = new TurtleNetwork(randotron, timeManager, rootOutputDirectory);
107106

108107
generator = new TurtleTransactionGenerator(network, randotron);
109108

platform-sdk/consensus-otter-tests/src/testFixtures/java/org/hiero/otter/fixtures/turtle/TurtleTransactionGenerator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
package org.hiero.otter.fixtures.turtle;
33

44
import static java.util.Objects.requireNonNull;
5-
import static org.hiero.base.utility.ByteUtils.intToByteArray;
65

76
import com.swirlds.common.test.fixtures.Randotron;
87
import edu.umd.cs.findbugs.annotations.NonNull;
@@ -70,7 +69,8 @@ public void tick(@NonNull Instant now) {
7069
for (long i = previousCount; i < currentCount; i++) {
7170
for (final Node node : network.getNodes()) {
7271
// Generate a random transaction and submit it to the node.
73-
final byte[] transaction = intToByteArray(randotron.nextInt());
72+
final byte[] transaction = TransactionFactory.createEmptyTransaction(randotron.nextInt())
73+
.toByteArray();
7474
node.submitTransaction(transaction);
7575
}
7676
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
package org.hiero.otter.fixtures.turtle.app;
3+
4+
import com.hedera.hapi.node.base.Timestamp;
5+
import com.hedera.hapi.platform.event.StateSignatureTransaction;
6+
import com.hedera.node.app.hapi.utils.CommonPbjConverters;
7+
import com.hedera.pbj.runtime.io.buffer.Bytes;
8+
import com.swirlds.platform.state.service.WritablePlatformStateStore;
9+
import com.swirlds.platform.test.fixtures.turtle.runner.TurtleTestingToolState;
10+
import edu.umd.cs.findbugs.annotations.NonNull;
11+
import java.util.function.Consumer;
12+
import org.hiero.base.utility.CommonUtils;
13+
import org.hiero.consensus.model.event.Event;
14+
import org.hiero.consensus.model.transaction.ScopedSystemTransaction;
15+
16+
/**
17+
* Utility class to handle transactions in the Turtle testing tool.
18+
*/
19+
public class TransactionHandlers {
20+
21+
private TransactionHandlers() {}
22+
23+
/**
24+
* Handles the transaction based on its type.
25+
*
26+
* @param state the current state of the Turtle testing tool
27+
* @param event the event associated with the transaction
28+
* @param transaction the transaction to handle
29+
* @param callback the callback to invoke with the new ScopedSystemTransaction
30+
*/
31+
public static void handleTransaction(
32+
@NonNull final TurtleTestingToolState state,
33+
@NonNull final Event event,
34+
@NonNull final TurtleTransaction transaction,
35+
@NonNull Consumer<ScopedSystemTransaction<StateSignatureTransaction>> callback) {
36+
switch (transaction.getDataCase()) {
37+
case FREEZETRANSACTION -> handleFreeze(state, transaction.getFreezeTransaction());
38+
case STATESIGNATURETRANSACTION ->
39+
handleStateSignature(event, transaction.getStateSignatureTransaction(), callback);
40+
}
41+
}
42+
43+
/**
44+
* Handles the freeze transaction by updating the freeze time in the platform state.
45+
*
46+
* @param state the current state of the Turtle testing tool
47+
* @param freezeTransaction the freeze transaction to handle
48+
*/
49+
public static void handleFreeze(
50+
@NonNull final TurtleTestingToolState state, @NonNull final TurtleFreezeTransaction freezeTransaction) {
51+
final Timestamp freezeTime = CommonPbjConverters.toPbj(freezeTransaction.getFreezeTime());
52+
WritablePlatformStateStore store =
53+
new WritablePlatformStateStore(state.getWritableStates("PlatformStateService"));
54+
store.setFreezeTime(CommonUtils.fromPbjTimestamp(freezeTime));
55+
}
56+
57+
/**
58+
* Handles the state signature transaction by creating a new ScopedSystemTransaction and passing it to the callback.
59+
*
60+
* @param event the event associated with the transaction
61+
* @param transaction the state signature transaction to handle
62+
* @param callback the callback to invoke with the new ScopedSystemTransaction
63+
*/
64+
public static void handleStateSignature(
65+
@NonNull final Event event,
66+
@NonNull final com.hedera.hapi.platform.event.legacy.StateSignatureTransaction transaction,
67+
@NonNull final Consumer<ScopedSystemTransaction<StateSignatureTransaction>> callback) {
68+
final StateSignatureTransaction newTransaction = new StateSignatureTransaction(
69+
transaction.getRound(),
70+
Bytes.wrap(transaction.getSignature().toByteArray()),
71+
Bytes.wrap(transaction.getHash().toByteArray()));
72+
callback.accept(
73+
new ScopedSystemTransaction<>(event.getCreatorId(), event.getSoftwareVersion(), newTransaction));
74+
}
75+
}

0 commit comments

Comments
 (0)