diff --git a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/utility/AutoCloseableWrapper.java b/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/utility/AutoCloseableWrapper.java index 17f75ac18193..835c4ac48d40 100644 --- a/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/utility/AutoCloseableWrapper.java +++ b/platform-sdk/swirlds-common/src/main/java/com/swirlds/common/utility/AutoCloseableWrapper.java @@ -23,7 +23,7 @@ * the type of the wrapped object */ public class AutoCloseableWrapper implements AutoCloseable { - + private static final AutoCloseableWrapper EMPTY = new AutoCloseableWrapper<>(null, () -> {}); private final T object; private final Runnable closeCallback; @@ -56,4 +56,14 @@ public T get() { public void close() { closeCallback.run(); } + + /** + * Get an empty wrapper. + * + * @return an empty wrapper + */ + @SuppressWarnings("unchecked") + public static AutoCloseableWrapper empty() { + return (AutoCloseableWrapper) EMPTY; + } } diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java index 47117b8ac857..2f0a85390b35 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java @@ -21,6 +21,7 @@ import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; import static com.swirlds.logging.legacy.LogMarker.RECONNECT; import static com.swirlds.logging.legacy.LogMarker.STARTUP; +import static com.swirlds.logging.legacy.LogMarker.STATE_TO_DISK; import static com.swirlds.platform.event.creation.EventCreationManagerFactory.buildEventCreationManager; import static com.swirlds.platform.event.creation.EventCreationManagerFactory.buildLegacyEventCreationManager; import static com.swirlds.platform.state.address.AddressBookMetrics.registerAddressBookMetrics; @@ -153,6 +154,7 @@ import com.swirlds.platform.state.iss.IssScratchpad; import com.swirlds.platform.state.nexus.EmergencyStateNexus; import com.swirlds.platform.state.nexus.LatestCompleteStateNexus; +import com.swirlds.platform.state.nexus.SignedStateNexus; import com.swirlds.platform.state.signed.ReservedSignedState; import com.swirlds.platform.state.signed.SavedStateInfo; import com.swirlds.platform.state.signed.SignedState; @@ -161,6 +163,7 @@ import com.swirlds.platform.state.signed.SignedStateMetrics; import com.swirlds.platform.state.signed.SourceOfSignedState; import com.swirlds.platform.state.signed.StartupStateUtils; +import com.swirlds.platform.state.signed.StateDumpRequest; import com.swirlds.platform.state.signed.StateToDiskReason; import com.swirlds.platform.stats.StatConstructor; import com.swirlds.platform.system.InitTrigger; @@ -239,6 +242,18 @@ public class SwirldsPlatform implements Platform { private final long initialMinimumGenerationNonAncient; private final StateManagementComponent stateManagementComponent; + /** Manages the pipeline of signed states to be written to disk */ + private final SignedStateFileManager signedStateFileManager; + + /** + * Holds the latest state that is immutable. May be unhashed (in the future), may or may not have all required + * signatures. State is returned with a reservation. + *

+ * NOTE: This is currently set when a state has finished hashing. In the future, this will be set at the moment a + * new state is created, before it is hashed. + */ + private final SignedStateNexus latestImmutableState = new SignedStateNexus(); + private final QueueThread intakeQueue; private final QueueThread stateHashSignQueue; private final EventLinker eventLinker; @@ -494,8 +509,7 @@ public class SwirldsPlatform implements Platform { components.add(new IssMetrics(platformContext.getMetrics(), currentAddressBook)); - // Manages the pipeline of signed states to be written to disk - final SignedStateFileManager signedStateFileManager = new SignedStateFileManager( + signedStateFileManager = new SignedStateFileManager( platformContext, new SignedStateMetrics(platformContext.getMetrics()), Time.getCurrent(), @@ -535,7 +549,6 @@ public class SwirldsPlatform implements Platform { newLatestCompleteStateConsumer, this::handleFatalError, savedStateController, - platformWiring.getDumpStateToDiskInput()::put, platformWiring.getSignStateInput()::put); // Load the minimum generation into the pre-consensus event writer @@ -610,6 +623,7 @@ public class SwirldsPlatform implements Platform { appVersion); final InterruptableConsumer newSignedStateFromTransactionsConsumer = rs -> { + latestImmutableState.setState(rs.getAndReserve("newSignedStateFromTransactionsConsumer")); latestCompleteState.newIncompleteState(rs.get().getRound()); stateManagementComponent.newSignedStateFromTransactions(rs); }; @@ -842,7 +856,7 @@ public class SwirldsPlatform implements Platform { } else { initialMinimumGenerationNonAncient = initialState.getState().getPlatformState().getPlatformData().getMinimumGenerationNonAncient(); - + latestImmutableState.setState(initialState.reserve("set latest immutable to initial state")); stateManagementComponent.stateToLoad(initialState, SourceOfSignedState.DISK); consensusRoundHandler.loadDataFromSignedState(initialState, false); @@ -1095,6 +1109,7 @@ private void loadReconnectState(final SignedState signedState) { // kick off transition to RECONNECT_COMPLETE before beginning to save the reconnect state to disk // this guarantees that the platform status will be RECONNECT_COMPLETE before the state is saved platformStatusManager.submitStatusAction(new ReconnectCompleteAction(signedState.getRound())); + latestImmutableState.setState(signedState.reserve("set latest immutable to reconnect state")); stateManagementComponent.stateToLoad(signedState, SourceOfSignedState.RECONNECT); loadStateIntoConsensus(signedState); @@ -1277,7 +1292,22 @@ public void performPcesRecovery() { eventCreator.start(); } replayPreconsensusEvents(); - stateManagementComponent.dumpLatestImmutableState(StateToDiskReason.PCES_RECOVERY_COMPLETE, true); + try (final ReservedSignedState reservedState = latestImmutableState.getState("Get PCES recovery state")) { + if (reservedState == null) { + logger.warn( + STATE_TO_DISK.getMarker(), + "Trying to dump PCES recovery state to disk, but no state is available."); + } else { + final SignedState signedState = reservedState.get(); + signedState.markAsStateToSave(StateToDiskReason.PCES_RECOVERY_COMPLETE); + + final StateDumpRequest request = + StateDumpRequest.create(signedState.reserve("dumping PCES recovery state")); + + signedStateFileManager.dumpStateTask(request); + request.waitForFinished().run(); + } + } } /** @@ -1305,8 +1335,8 @@ private void replayPreconsensusEvents() { intakeQueue, consensusRoundHandler, stateHashSignQueue, - stateManagementComponent, initialMinimumGenerationNonAncient, + () -> latestImmutableState.getState("PCES replay"), platformWiring::flushIntakePipeline); } @@ -1363,10 +1393,12 @@ public AddressBook getAddressBook() { */ @SuppressWarnings("unchecked") @Override - public AutoCloseableWrapper getLatestImmutableState(@NonNull final String reason) { - final ReservedSignedState wrapper = stateManagementComponent.getLatestImmutableState(reason); - return new AutoCloseableWrapper<>( - wrapper.isNull() ? null : (T) wrapper.get().getState().getSwirldState(), wrapper::close); + public @NonNull AutoCloseableWrapper getLatestImmutableState( + @NonNull final String reason) { + final ReservedSignedState wrapper = latestImmutableState.getState(reason); + return wrapper == null + ? AutoCloseableWrapper.empty() + : new AutoCloseableWrapper<>((T) wrapper.get().getState().getSwirldState(), wrapper::close); } /** diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/DefaultStateManagementComponent.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/DefaultStateManagementComponent.java index 1ac3aec8b40a..1b1d0d9eda3e 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/DefaultStateManagementComponent.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/DefaultStateManagementComponent.java @@ -16,9 +16,6 @@ package com.swirlds.platform.components.state; -import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; -import static com.swirlds.logging.legacy.LogMarker.STATE_TO_DISK; - import com.swirlds.base.time.Time; import com.swirlds.common.config.StateConfig; import com.swirlds.common.context.PlatformContext; @@ -37,26 +34,17 @@ import com.swirlds.platform.state.signed.SignedStateMetrics; import com.swirlds.platform.state.signed.SignedStateSentinel; import com.swirlds.platform.state.signed.SourceOfSignedState; -import com.swirlds.platform.state.signed.StateDumpRequest; -import com.swirlds.platform.state.signed.StateToDiskReason; import com.swirlds.platform.util.HashLogger; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.time.Instant; import java.util.List; import java.util.Objects; import java.util.function.Consumer; -import java.util.function.Predicate; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; /** * The default implementation of {@link StateManagementComponent}. */ public class DefaultStateManagementComponent implements StateManagementComponent { - private static final Logger logger = LogManager.getLogger(DefaultStateManagementComponent.class); - /** * Signed states are deleted on this background thread. */ @@ -83,7 +71,7 @@ public class DefaultStateManagementComponent implements StateManagementComponent private final SignedStateSentinel signedStateSentinel; private final SavedStateController savedStateController; - private final Consumer stateDumpConsumer; + private final Consumer stateSigner; /** @@ -94,7 +82,6 @@ public class DefaultStateManagementComponent implements StateManagementComponent * @param newLatestCompleteStateConsumer consumer to invoke when there is a new latest complete signed state * @param fatalErrorConsumer consumer to invoke when a fatal error has occurred * @param savedStateController controls which states are saved to disk - * @param stateDumpConsumer consumer to invoke when a state is requested to be dumped to disk */ public DefaultStateManagementComponent( @NonNull final PlatformContext platformContext, @@ -103,7 +90,6 @@ public DefaultStateManagementComponent( @NonNull final NewLatestCompleteStateConsumer newLatestCompleteStateConsumer, @NonNull final FatalErrorConsumer fatalErrorConsumer, @NonNull final SavedStateController savedStateController, - @NonNull final Consumer stateDumpConsumer, @NonNull final Consumer stateSigner) { Objects.requireNonNull(platformContext); @@ -116,7 +102,6 @@ public DefaultStateManagementComponent( this.signedStateGarbageCollector = new SignedStateGarbageCollector(threadManager, signedStateMetrics); this.signedStateSentinel = new SignedStateSentinel(platformContext, threadManager, Time.getCurrent()); this.savedStateController = Objects.requireNonNull(savedStateController); - this.stateDumpConsumer = Objects.requireNonNull(stateDumpConsumer); this.stateSigner = Objects.requireNonNull(stateSigner); hashLogger = @@ -167,36 +152,10 @@ private void newSignedStateBeingTracked(final SignedState signedState, final Sou } } - /** - * Checks if the signed state's round is older than the round of the latest state in the signed state manager. - * - * @param signedState the signed state whose round needs to be compared to the latest state in the signed state - * manager. - * @return true if the signed state's round is < the round of the latest state in the signed state manager, - * otherwise false. - */ - private boolean stateRoundIsTooOld(final SignedState signedState) { - final long roundOfLatestState = signedStateManager.getLastImmutableStateRound(); - if (signedState.getRound() < roundOfLatestState) { - logger.error( - EXCEPTION.getMarker(), - "State received from transactions is in an incorrect order. " - + "Latest state is from round {}, provided state is from round {}", - roundOfLatestState, - signedState.getRound()); - return true; - } - return false; - } - @Override public void newSignedStateFromTransactions(@NonNull final ReservedSignedState signedState) { try (signedState) { signedState.get().setGarbageCollector(signedStateGarbageCollector); - - if (stateRoundIsTooOld(signedState.get())) { - return; // do not process older states. - } signedStateHasher.hashState(signedState.get()); newSignedStateBeingTracked(signedState.get(), SourceOfSignedState.TRANSACTIONS); @@ -207,14 +166,6 @@ public void newSignedStateFromTransactions(@NonNull final ReservedSignedState si } } - /** - * {@inheritDoc} - */ - @Override - public ReservedSignedState getLatestImmutableState(@NonNull final String reason) { - return signedStateManager.getLatestImmutableState(reason); - } - /** * {@inheritDoc} */ @@ -251,76 +202,6 @@ public void stop() { signedStateGarbageCollector.stop(); } - /** - * {@inheritDoc} - */ - @NonNull - @Override - public ReservedSignedState find(final @NonNull Predicate criteria, @NonNull final String reason) { - return signedStateManager.find(criteria, reason); - } - - @Override - public void dumpLatestImmutableState(@NonNull final StateToDiskReason reason, final boolean blocking) { - Objects.requireNonNull(reason); - - try (final ReservedSignedState reservedState = signedStateManager.getLatestImmutableState( - "DefaultStateManagementComponent.dumpLatestImmutableState()")) { - - if (reservedState.isNull()) { - logger.warn(STATE_TO_DISK.getMarker(), "State dump requested, but no state is available."); - } else { - dumpState(reservedState.get(), reason, blocking); - } - } - } - - /** - * Dump a state to disk out-of-band. - *

- * Writing a state "out-of-band" means the state is being written for the sake of a human, whether for debug - * purposes, or because of a fault. States written out-of-band will not be read automatically by the platform, and - * will not be used as an initial state at boot time. - *

- * A dumped state will be saved in a subdirectory of the signed states base directory, with the subdirectory being - * named after the reason the state is being written out-of-band. - * - * @param signedState the signed state to write to disk - * @param reason the reason why the state is being written out-of-band - * @param blocking if true then block until the state has been fully written to disk - */ - private void dumpState( - @NonNull final SignedState signedState, @NonNull final StateToDiskReason reason, final boolean blocking) { - Objects.requireNonNull(signedState); - Objects.requireNonNull(reason); - signedState.markAsStateToSave(reason); - - final StateDumpRequest request = StateDumpRequest.create(signedState.reserve("dumping to disk")); - - stateDumpConsumer.accept(request); - - if (blocking) { - request.waitForFinished().run(); - } - } - - /** - * {@inheritDoc} - */ - @Override - @Nullable - public Instant getFirstStateTimestamp() { - return signedStateManager.getFirstStateTimestamp(); - } - - /** - * {@inheritDoc} - */ - @Override - public long getFirstStateRound() { - return signedStateManager.getFirstStateRound(); - } - /** * {@inheritDoc} */ diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/StateManagementComponent.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/StateManagementComponent.java index e499936b6c9f..b93beb72eb28 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/StateManagementComponent.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/components/state/StateManagementComponent.java @@ -19,14 +19,9 @@ import com.swirlds.platform.components.PlatformComponent; import com.swirlds.platform.components.common.output.NewSignedStateFromTransactionsConsumer; import com.swirlds.platform.components.common.output.SignedStateToLoadConsumer; -import com.swirlds.platform.state.signed.ReservedSignedState; -import com.swirlds.platform.state.signed.SignedStateFinder; import com.swirlds.platform.state.signed.SignedStateInfo; import com.swirlds.platform.state.signed.SignedStateManager; -import com.swirlds.platform.state.signed.StateToDiskReason; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.time.Instant; import java.util.List; /** @@ -41,20 +36,7 @@ * */ public interface StateManagementComponent - extends PlatformComponent, - SignedStateFinder, - SignedStateToLoadConsumer, - NewSignedStateFromTransactionsConsumer { - - /** - * Get a reserved instance of the latest immutable signed state. May be unhashed, may or may not have all required - * signatures. State is returned with a reservation. - * - * @param reason a short description of why this SignedState is being reserved. Each location where a SignedState is - * reserved should attempt to use a unique reason, as this makes debugging reservation bugs easier. - * @return a reserved signed state, may contain null if none currently in memory are complete - */ - ReservedSignedState getLatestImmutableState(@NonNull final String reason); + extends PlatformComponent, SignedStateToLoadConsumer, NewSignedStateFromTransactionsConsumer { /** * Get the latest signed states stored by this component. This method creates a copy, so no changes to the array @@ -67,32 +49,6 @@ public interface StateManagementComponent @Deprecated List getSignedStateInfo(); - /** - * Dump the latest immutable state if it is available. - * - * @param reason the reason why the state is being dumped - * @param blocking if true then block until the state dump is complete - */ - void dumpLatestImmutableState(@NonNull StateToDiskReason reason, boolean blocking); - - /** - * Get the consensus timestamp of the first state ingested by the signed state manager. Useful for computing the - * total consensus time that this node has been operating for. - * - * @return the consensus timestamp of the first state ingested by the signed state manager, or null if no states - * have been ingested yet - */ - @Nullable - Instant getFirstStateTimestamp(); - - /** - * Get the round of the first state ingested by the signed state manager. Useful for computing the total number of - * elapsed rounds since startup. - * - * @return the round of the first state ingested by the signed state manager, or -1 if no states have been ingested - */ - long getFirstStateRound(); - /** * Get the signed state manager. */ diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PreconsensusEventReplayWorkflow.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PreconsensusEventReplayWorkflow.java index 67d95ff4aa7f..0cb62ea4dd6b 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PreconsensusEventReplayWorkflow.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/event/preconsensus/PreconsensusEventReplayWorkflow.java @@ -29,14 +29,15 @@ import com.swirlds.common.threading.framework.QueueThread; import com.swirlds.common.threading.interrupt.InterruptableConsumer; import com.swirlds.common.threading.manager.ThreadManager; -import com.swirlds.platform.components.state.StateManagementComponent; import com.swirlds.platform.event.GossipEvent; import com.swirlds.platform.eventhandling.ConsensusRoundHandler; import com.swirlds.platform.state.signed.ReservedSignedState; import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import java.time.Duration; import java.time.Instant; import java.util.Objects; +import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -60,8 +61,8 @@ private PreconsensusEventReplayWorkflow() {} * @param intakeQueue the queue thread for the event intake component * @param consensusRoundHandler the object responsible for applying transactions to consensus rounds * @param stateHashSignQueue the queue thread for hashing and signing states - * @param stateManagementComponent manages various copies of the state * @param initialMinimumGenerationNonAncient the minimum generation of events to replay + * @param latestImmutableState provides the latest immutable state if available * @param flushIntakePipeline flushes the intake pipeline. only used if the new intake pipeline is * enabled */ @@ -75,8 +76,8 @@ public static void replayPreconsensusEvents( @NonNull final QueueThread intakeQueue, @NonNull final ConsensusRoundHandler consensusRoundHandler, @NonNull final QueueThread stateHashSignQueue, - @NonNull final StateManagementComponent stateManagementComponent, final long initialMinimumGenerationNonAncient, + @NonNull final Supplier latestImmutableState, @NonNull Runnable flushIntakePipeline) { Objects.requireNonNull(platformContext); @@ -88,7 +89,7 @@ public static void replayPreconsensusEvents( Objects.requireNonNull(intakeQueue); Objects.requireNonNull(consensusRoundHandler); Objects.requireNonNull(stateHashSignQueue); - Objects.requireNonNull(stateManagementComponent); + Objects.requireNonNull(latestImmutableState); logger.info( STARTUP.getMarker(), @@ -97,6 +98,17 @@ public static void replayPreconsensusEvents( try { final Instant start = time.now(); + final Instant firstStateTimestamp; + final long firstStateRound; + try (final ReservedSignedState startState = latestImmutableState.get()) { + if (startState == null || startState.isNull()) { + firstStateTimestamp = null; + firstStateRound = -1; + } else { + firstStateTimestamp = startState.get().getConsensusTimestamp(); + firstStateRound = startState.get().getRound(); + } + } final IOIterator iterator = preconsensusEventFileManager.getEventIterator(initialMinimumGenerationNonAncient); @@ -117,7 +129,9 @@ public static void replayPreconsensusEvents( final Duration elapsed = Duration.between(start, finish); logReplayInfo( - stateManagementComponent, + firstStateTimestamp, + firstStateRound, + latestImmutableState, eventReplayPipeline.getEventCount(), eventReplayPipeline.getTransactionCount(), elapsed); @@ -163,15 +177,16 @@ private static void waitForReplayToComplete( * Write information about the replay to disk. */ private static void logReplayInfo( - @NonNull final StateManagementComponent stateManagementComponent, + @Nullable final Instant firstTimestamp, + final long firstRound, + @NonNull final Supplier latestImmutableState, final long eventCount, final long transactionCount, @NonNull final Duration elapsedTime) { - try (final ReservedSignedState latestConsensusRound = - stateManagementComponent.getLatestImmutableState("SwirldsPlatform.replayPreconsensusEventStream()")) { + try (final ReservedSignedState latestConsensusRound = latestImmutableState.get()) { - if (latestConsensusRound.isNull()) { + if (latestConsensusRound == null || latestConsensusRound.isNull()) { logger.info( STARTUP.getMarker(), "Replayed {} preconsensus events. No rounds reached consensus.", @@ -179,9 +194,6 @@ private static void logReplayInfo( return; } - final Instant firstTimestamp = stateManagementComponent.getFirstStateTimestamp(); - final long firstRound = stateManagementComponent.getFirstStateRound(); - if (firstTimestamp == null) { // This should be impossible. If we have a state, we should have a timestamp. logger.error( diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/SignedStateManager.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/SignedStateManager.java index d3f4bb192aab..cbb87e51c9c6 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/SignedStateManager.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/signed/SignedStateManager.java @@ -156,15 +156,6 @@ public SignedStateManager( return lastState.getAndReserve(reason); } - /** - * Get the round of the latest immutable signed state. - * - * @return the round of the latest immutable signed state. - */ - public long getLastImmutableStateRound() { - return lastState.getRound(); - } - /** *

* Get the latest signed states stored by this manager. diff --git a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/state/StateManagementComponentTests.java b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/state/StateManagementComponentTests.java index 961a5423919f..0bdee0ea49e7 100644 --- a/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/state/StateManagementComponentTests.java +++ b/platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/components/state/StateManagementComponentTests.java @@ -19,7 +19,6 @@ import static com.swirlds.platform.state.manager.SignedStateManagerTestUtils.buildFakeSignature; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; @@ -174,78 +173,6 @@ void stateSignaturesAppliedAndTracked() { component.stop(); } - @Test - @DisplayName("Signed States For Old Rounds Are Not Processed") - void signedStateFromTransactionsCodePath() { - final Random random = RandomUtils.getRandomPrintSeed(); - final DefaultStateManagementComponent component = newStateManagementComponent(); - - systemTransactionConsumer.reset(); - component.start(); - - final SignedState signedStateRound1 = new RandomSignedStateGenerator(random) - .setRound(1) - .setSigningNodeIds(List.of()) - .build(); - signedStateRound1.getState().setHash(null); - - final SignedState signedStateRound2 = new RandomSignedStateGenerator(random) - .setRound(2) - .setSigningNodeIds(List.of()) - .build(); - signedStateRound2.getState().setHash(null); - - final SignedState signedStateRound3 = new RandomSignedStateGenerator(random) - .setRound(3) - .setSigningNodeIds(List.of()) - .build(); - signedStateRound3.getState().setHash(null); - - // Transaction proceeds, state is hashed, signature of hash sent, and state is set as last state. - component.newSignedStateFromTransactions(signedStateRound2.reserve("test")); - assertNotNull( - signedStateRound2.getState().getHash(), - "The hash for transaction states that are processed will not be null."); - assertEquals( - systemTransactionConsumer.getNumSubmitted(), - 1, - "The transaction could should be 1 for processing a valid state."); - assertEquals( - component.getLatestImmutableState("test").get(), - signedStateRound2, - "The last state should be the same as the signed state for round 2."); - - // Transaction fails to be signed due to lower round. - component.newSignedStateFromTransactions(signedStateRound1.reserve("test")); - assertNull( - signedStateRound1.getState().getHash(), - "The states with older rounds will not have their hash computed."); - assertEquals( - systemTransactionConsumer.getNumSubmitted(), - 1, - "The states with older rounds will not have hash signatures transmitted."); - assertEquals( - component.getLatestImmutableState("test").get(), - signedStateRound2, - "The states with older rounds will not be saved as the latest state."); - - // Transaction proceeds, state is hashed, signature of hash sent, and state is set as last state. - component.newSignedStateFromTransactions(signedStateRound3.reserve("test")); - assertNotNull( - signedStateRound3.getState().getHash(), - "The state should be processed and have a hash computed and set."); - assertEquals( - systemTransactionConsumer.getNumSubmitted(), - 2, - "The signed hash for processed states will be transmitted."); - assertEquals( - component.getLatestImmutableState("test").get(), - signedStateRound3, - "The processed state should be set as the latest state in teh signed state manager."); - - component.stop(); - } - @Test @DisplayName("Test that the state is saved to disk when it is received via reconnect") void testReconnectStateSaved() { @@ -375,7 +302,6 @@ private DefaultStateManagementComponent newStateManagementComponent( newLatestCompleteStateConsumer::consume, (msg, t, code) -> {}, controller, - r -> {}, signer); dispatchBuilder.start(); diff --git a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PreconsensusEventReplayWorkflowTests.java b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PreconsensusEventReplayWorkflowTests.java index 76165edc61c6..4e74027c127a 100644 --- a/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PreconsensusEventReplayWorkflowTests.java +++ b/platform-sdk/swirlds-unit-tests/core/swirlds-platform-test/src/test/java/com/swirlds/platform/test/event/preconsensus/PreconsensusEventReplayWorkflowTests.java @@ -34,7 +34,6 @@ import com.swirlds.common.context.PlatformContext; import com.swirlds.common.threading.framework.QueueThread; import com.swirlds.common.threading.manager.AdHocThreadManager; -import com.swirlds.platform.components.state.StateManagementComponent; import com.swirlds.platform.event.GossipEvent; import com.swirlds.platform.event.preconsensus.PreconsensusEventFileManager; import com.swirlds.platform.event.preconsensus.PreconsensusEventMultiFileIterator; @@ -152,14 +151,12 @@ void testBasicReplayWorkflow() throws InterruptedException { .when(preconsensusEventWriter) .beginStreamingNewEvents(); - final StateManagementComponent stateManagementComponent = mock(StateManagementComponent.class); final ReservedSignedState latestImmutableState = mock(ReservedSignedState.class); when(latestImmutableState.isNull()).thenReturn(false); final SignedState signedState = mock(SignedState.class); when(signedState.getRound()).thenReturn(random.nextLong(1, 10000)); when(signedState.getConsensusTimestamp()).thenReturn(randomInstant(random)); when(latestImmutableState.get()).thenReturn(signedState); - when(stateManagementComponent.getLatestImmutableState(any())).thenReturn(latestImmutableState); final PlatformContext platformContext = TestPlatformContextBuilder.create().build(); @@ -174,8 +171,8 @@ void testBasicReplayWorkflow() throws InterruptedException { eventIntakeTaskQueueThread, consensusRoundHandler, stateHashSignQueue, - stateManagementComponent, minimumGenerationNonAncient, + () -> latestImmutableState, () -> {}); assertEquals(TestPhase.TEST_FINISHED, phase.get());