From 539f059126acd770b7f68eabc7b374a3250054e2 Mon Sep 17 00:00:00 2001 From: Ivan Malygin Date: Thu, 28 Nov 2024 08:54:28 -0500 Subject: [PATCH] fix: 16750 Fixed serialization for `ISSTestingToolState` (#16826) Signed-off-by: Ivan Malygin --- .../swirlds/demo/iss/ISSTestingToolState.java | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java b/platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java index e48527ead7f7..994c44114486 100644 --- a/platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java +++ b/platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java @@ -36,6 +36,9 @@ import com.hedera.hapi.node.state.roster.Roster; import com.hedera.hapi.node.state.roster.RosterEntry; import com.swirlds.common.constructable.ConstructableIgnored; +import com.swirlds.common.io.SelfSerializable; +import com.swirlds.common.io.streams.SerializableDataInputStream; +import com.swirlds.common.io.streams.SerializableDataOutputStream; import com.swirlds.common.merkle.utility.SerializableLong; import com.swirlds.common.platform.NodeId; import com.swirlds.common.utility.ByteUtils; @@ -50,8 +53,13 @@ import com.swirlds.platform.system.events.ConsensusEvent; import com.swirlds.platform.system.transaction.ConsensusTransaction; import com.swirlds.platform.test.fixtures.state.FakeMerkleStateLifecycles; +import com.swirlds.state.merkle.singleton.StringLeaf; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; import java.util.HashMap; @@ -62,6 +70,7 @@ import java.util.Objects; import java.util.Random; import java.util.function.Function; +import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -89,6 +98,11 @@ private static class ClassVersion { */ private static final Duration INCIDENT_WINDOW = Duration.ofSeconds(10); + private static final int RUNNING_SUM_INDEX = 1; + private static final int GENESIS_TIMESTAMP_INDEX = 2; + private static final int PLANNED_ISS_LIST_INDEX = 3; + private static final int PLANNED_LOG_ERROR_LIST_INDEX = 4; + private NodeId selfId; /** @@ -172,6 +186,19 @@ public void init( this.plannedIssList = testingToolConfig.getPlannedISSs(); this.plannedLogErrorList = testingToolConfig.getPlannedLogErrors(); + writeObjectByChildIndex(PLANNED_ISS_LIST_INDEX, plannedIssList); + writeObjectByChildIndex(PLANNED_LOG_ERROR_LIST_INDEX, plannedLogErrorList); + } else { + StringLeaf runningSumLeaf = getChild(RUNNING_SUM_INDEX); + if (runningSumLeaf != null) { + runningSum = Long.parseLong(runningSumLeaf.getLabel()); + } + StringLeaf genesisTimestampLeaf = getChild(GENESIS_TIMESTAMP_INDEX); + if (genesisTimestampLeaf != null) { + genesisTimestamp = Instant.parse(genesisTimestampLeaf.getLabel()); + } + plannedIssList = readObjectByChildIndex(PLANNED_ISS_LIST_INDEX, PlannedIss::new); + plannedLogErrorList = readObjectByChildIndex(PLANNED_LOG_ERROR_LIST_INDEX, PlannedLogError::new); } this.selfId = platform.getSelfId(); @@ -179,6 +206,32 @@ public void init( Scratchpad.create(platform.getContext(), selfId, IssTestingToolScratchpad.class, "ISSTestingTool"); } + List readObjectByChildIndex(int index, Supplier factory) { + StringLeaf stringValue = getChild(index); + if (stringValue != null) { + try { + SerializableDataInputStream in = new SerializableDataInputStream( + new ByteArrayInputStream(stringValue.getLabel().getBytes(StandardCharsets.UTF_8))); + return in.readSerializableList(1024, false, factory); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + return null; + } + } + + void writeObjectByChildIndex(int index, List list) { + try { + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + SerializableDataOutputStream out = new SerializableDataOutputStream(byteOut); + out.writeSerializableList(list, false, true); + setChild(index, new StringLeaf(byteOut.toString(StandardCharsets.UTF_8))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * {@inheritDoc} */ @@ -221,6 +274,7 @@ public void handleConsensusRound(final Round round, final PlatformStateModifier private void captureTimestamp(final ConsensusEvent event) { if (genesisTimestamp == null) { genesisTimestamp = event.getConsensusTimestamp(); + setChild(GENESIS_TIMESTAMP_INDEX, new StringLeaf(genesisTimestamp.toString())); } } @@ -236,6 +290,7 @@ private void handleTransaction(final ConsensusTransaction transaction) { final int delta = ByteUtils.byteArrayToInt(transaction.getApplicationTransaction().toByteArray(), 0); runningSum += delta; + setChild(RUNNING_SUM_INDEX, new StringLeaf(Long.toString(runningSum))); } /** @@ -325,7 +380,7 @@ private int findLargestPartition(@NonNull final Roster roster, @NonNull final Pl int largestPartition = 0; long largestPartitionWeight = 0; for (int partition = 0; partition < plannedIss.getPartitionCount(); partition++) { - if (partitionWeights.get(partition) > largestPartitionWeight) { + if (partitionWeights.get(partition) != null && partitionWeights.get(partition) > largestPartitionWeight) { largestPartition = partition; largestPartitionWeight = partitionWeights.getOrDefault(partition, 0L); }