Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,6 @@ protected HederaVirtualMapState copyingConstructor() {
return new HederaVirtualMapState(this);
}

/**
* Creates a new instance of {@link HederaVirtualMapState} with the specified {@link VirtualMap}.
*
* @param virtualMap the virtual map whose metrics must already be registered
* @param metrics the platform metric instance to use when creating the new instance of state
* @param time the time instance to use when creating the new instance of state
* @return a new instance of {@link HederaVirtualMapState}
*/
@Override
protected HederaVirtualMapState newInstance(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
return new HederaVirtualMapState(virtualMap, metrics, time);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@
import com.hedera.node.app.spi.fixtures.TestSchema;
import com.hedera.node.app.spi.migrate.StartupNetworks;
import com.hedera.node.config.data.HederaConfig;
import com.swirlds.base.test.fixtures.time.FakeTime;
import com.swirlds.common.io.utility.LegacyTemporaryFileBuilder;
import com.swirlds.common.merkle.utility.MerkleTreeSnapshotReader;
import com.swirlds.common.metrics.noop.NoOpMetrics;
import com.swirlds.config.api.Configuration;
import com.swirlds.config.extensions.sources.SimpleConfigSource;
import com.swirlds.config.extensions.test.fixtures.TestConfigBuilder;
import com.swirlds.platform.state.signed.SignedState;
import com.swirlds.platform.test.fixtures.state.RandomSignedStateGenerator;
import com.swirlds.state.MerkleNodeState;
import com.swirlds.state.State;
import com.swirlds.state.StateLifecycleManager;
import com.swirlds.state.lifecycle.MigrationContext;
import com.swirlds.state.lifecycle.Schema;
import com.swirlds.state.lifecycle.StateDefinition;
import com.swirlds.state.merkle.StateLifecycleManagerImpl;
import com.swirlds.state.merkle.disk.OnDiskReadableKVState;
import com.swirlds.state.merkle.disk.OnDiskWritableKVState;
import com.swirlds.state.spi.ReadableKVState;
Expand Down Expand Up @@ -157,11 +161,12 @@ private void forceFlush(ReadableKVState<?, ?> state) {
@ParameterizedTest
@ValueSource(booleans = {true, false})
void simpleReadAndWrite(boolean forceFlush) throws IOException, ConstructableRegistryException {
final var schemaV1 = createV1Schema();
final var originalTree = createMerkleHederaState(schemaV1);
final Schema schemaV1 = createV1Schema();
final StateLifecycleManager stateLifecycleManager = createStateLifecycleManager(schemaV1);
final MerkleNodeState originalTree = stateLifecycleManager.getMutableState();

// When we serialize it to bytes and deserialize it back into a tree
MerkleNodeState copy = originalTree.copy(); // make a copy to make VM flushable
MerkleNodeState copy = stateLifecycleManager.copyMutableState(); // make a copy to make VM flushable
final byte[] serializedBytes;
if (forceFlush) {
// Force flush the VMs to disk to test serialization and deserialization
Expand All @@ -188,21 +193,22 @@ void simpleReadAndWrite(boolean forceFlush) throws IOException, ConstructableReg

@Test
void snapshot() throws IOException {
final var schemaV1 = createV1Schema();
final var originalTree = createMerkleHederaState(schemaV1);
final var tempDir = LegacyTemporaryFileBuilder.buildTemporaryDirectory(config);
final Schema<SemanticVersion> schemaV1 = createV1Schema();
final StateLifecycleManager stateLifecycleManager = createStateLifecycleManager(schemaV1);
final Path tempDir = LegacyTemporaryFileBuilder.buildTemporaryDirectory(config);
final MerkleNodeState originalTree = stateLifecycleManager.getLatestImmutableState();

// prepare the tree and create a snapshot
originalTree.copy().release();
stateLifecycleManager.getMutableState().release();
originalTree.computeHash();
originalTree.createSnapshot(tempDir);
stateLifecycleManager.createSnapshot(originalTree, tempDir);
originalTree.release();

final MerkleNodeState state =
originalTree.loadSnapshot(tempDir.resolve(MerkleTreeSnapshotReader.SIGNED_STATE_FILE_NAME));
stateLifecycleManager.loadSnapshot(tempDir.resolve(MerkleTreeSnapshotReader.SIGNED_STATE_FILE_NAME));
initServices(schemaV1, state);
assertTree(state);

originalTree.release();
state.release();
}

Expand All @@ -213,13 +219,16 @@ void snapshot() throws IOException {
*/
@Test
void dualReadAndWrite() throws IOException, ConstructableRegistryException {
final var schemaV1 = createV1Schema();
final var originalTree = createMerkleHederaState(schemaV1);
final Schema<SemanticVersion> schemaV1 = createV1Schema();
final StateLifecycleManager stateLifecycleManager = createStateLifecycleManager(schemaV1);
final MerkleNodeState originalTree = stateLifecycleManager.getMutableState();

MerkleNodeState copy = originalTree.copy(); // make a copy to make VM flushable
MerkleNodeState copy = stateLifecycleManager.copyMutableState(); // make a copy to make VM flushable

forceFlush(originalTree.getReadableStates(FIRST_SERVICE).get(FRUIT_STATE_ID));
copy.copy().release(); // make a fast copy because we can only write to disk an immutable copy
stateLifecycleManager
.copyMutableState()
.release(); // make a fast copy because we can only write to disk an immutable copy
copy.getRoot().getHash();
final byte[] serializedBytes = writeTree(copy.getRoot(), dir);

Expand Down Expand Up @@ -275,11 +284,11 @@ private void initServices(Schema<SemanticVersion> schemaV1, MerkleNodeState load
loadedTree.getRoot().migrate(MINIMUM_SUPPORTED_VERSION);
}

private MerkleNodeState createMerkleHederaState(Schema schemaV1) {
private StateLifecycleManager createStateLifecycleManager(Schema schemaV1) {
final SignedState randomState =
new RandomSignedStateGenerator().setRound(1).build();

final var originalTree = randomState.getState();
final MerkleNodeState originalTree = randomState.getState();
// the state is not hashed yet
final var originalTreeCopy = originalTree.copy();
originalTree.release();
Expand All @@ -295,7 +304,12 @@ private MerkleNodeState createMerkleHederaState(Schema schemaV1) {
migrationStateChanges,
startupNetworks,
TEST_PLATFORM_STATE_FACADE);
return originalTreeCopy;

final StateLifecycleManager stateLifecycleManager =
new StateLifecycleManagerImpl(new NoOpMetrics(), new FakeTime(), TestVirtualMapState::new);

stateLifecycleManager.initState(originalTreeCopy, true);
return stateLifecycleManager;
}

private static void populateVmCache(State loadedTree) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import com.swirlds.state.test.fixtures.MapWritableStates;
import com.swirlds.state.test.fixtures.merkle.TestVirtualMapState;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -305,7 +304,7 @@ public void initializeState(@NonNull final StateMetadata<?, ?> md) {
}

@Override
public MerkleNodeState loadSnapshot(@NonNull final Path targetPath) {
throw new UnsupportedOperationException();
public long getRound() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.hedera.hapi.block.stream.Block;
import com.hedera.hapi.block.stream.BlockItem;
import com.hedera.hapi.block.stream.output.StateChanges;
import com.hedera.node.app.HederaVirtualMapState;
import com.hedera.node.app.hapi.utils.blocks.BlockStreamAccess;
import com.hedera.node.app.hapi.utils.blocks.BlockStreamUtils;
import com.hedera.statevalidation.util.PlatformContextHelper;
Expand All @@ -18,6 +19,8 @@
import com.swirlds.platform.state.snapshot.DeserializedSignedState;
import com.swirlds.platform.state.snapshot.SignedStateFileWriter;
import com.swirlds.state.MerkleNodeState;
import com.swirlds.state.StateLifecycleManager;
import com.swirlds.state.merkle.StateLifecycleManagerImpl;
import com.swirlds.state.spi.CommittableWritableStates;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.io.IOException;
Expand Down Expand Up @@ -149,9 +152,18 @@ public void applyBlocks(
false,
DEFAULT_PLATFORM_STATE_FACADE);

final StateLifecycleManager stateLifecycleManager = new StateLifecycleManagerImpl(
platformContext.getMetrics(),
platformContext.getTime(),
vm -> new HederaVirtualMapState(vm, platformContext.getMetrics(), platformContext.getTime()));
try {
SignedStateFileWriter.writeSignedStateFilesToDirectory(
platformContext, selfId, outputPath, signedState, DEFAULT_PLATFORM_STATE_FACADE);
platformContext,
selfId,
outputPath,
signedState,
DEFAULT_PLATFORM_STATE_FACADE,
stateLifecycleManager);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,11 @@ protected OtterAppState copyingConstructor() {
return new OtterAppState(this);
}

@Override
protected OtterAppState newInstance(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
return new OtterAppState(virtualMap, metrics, time);
}

/**
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private StatsDemoState(final StatsDemoState sourceState) {
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ protected ConsistencyTestingToolState copyingConstructor() {
return new ConsistencyTestingToolState(this);
}

@Override
protected ConsistencyTestingToolState newInstance(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
return new ConsistencyTestingToolState(virtualMap, metrics, time);
}

/**
* Initialize the state
*/
Expand Down Expand Up @@ -160,7 +154,7 @@ void initState(Path logFilePath) {
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ protected ISSTestingToolState copyingConstructor() {
return new ISSTestingToolState(this);
}

@Override
protected ISSTestingToolState newInstance(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
return new ISSTestingToolState(virtualMap, metrics, time);
}

public void initState(InitTrigger trigger, Platform platform) {
throwIfImmutable();

Expand Down Expand Up @@ -198,7 +192,7 @@ List<PlannedLogError> getPlannedLogErrorList() {
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,11 @@ protected MigrationTestingToolState copyingConstructor() {
return new MigrationTestingToolState(this);
}

@Override
protected MigrationTestingToolState newInstance(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
return new MigrationTestingToolState(virtualMap, metrics, time);
}

/**
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ protected PlatformTestingToolState(final PlatformTestingToolState sourceState) {
* {@inheritDoc}
*/
@Override
protected long getRound() {
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.swirlds.platform.publisher.PlatformPublisher;
import com.swirlds.platform.reconnect.DefaultSignedStateValidator;
import com.swirlds.platform.reconnect.ReconnectController;
import com.swirlds.platform.state.SwirldStateManager;
import com.swirlds.platform.state.nexus.DefaultLatestCompleteStateNexus;
import com.swirlds.platform.state.nexus.LatestCompleteStateNexus;
import com.swirlds.platform.state.nexus.LockFreeStateNexus;
Expand All @@ -58,7 +57,9 @@
import com.swirlds.platform.system.status.actions.StartedReplayingEventsAction;
import com.swirlds.platform.wiring.PlatformComponents;
import com.swirlds.platform.wiring.PlatformCoordinator;
import com.swirlds.state.MerkleNodeState;
import com.swirlds.state.State;
import com.swirlds.state.StateLifecycleManager;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.time.Duration;
import java.util.List;
Expand Down Expand Up @@ -211,15 +212,16 @@
initializeState(this, platformContext, initialState, blocks.consensusStateEventHandler(), platformStateFacade);

// This object makes a copy of the state. After this point, initialState becomes immutable.
final SwirldStateManager swirldStateManager = blocks.swirldStateManager();
swirldStateManager.setState(initialState.getState(), true);
platformStateFacade.setCreationSoftwareVersionTo(swirldStateManager.getConsensusState(), blocks.appVersion());
final StateLifecycleManager stateLifecycleManager = blocks.stateLifecycleManager();
final MerkleNodeState state = initialState.getState();
stateLifecycleManager.initState(state, true);
platformStateFacade.setCreationSoftwareVersionTo(stateLifecycleManager.getMutableState(), blocks.appVersion());

Check warning on line 218 in platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java#L215-L218

Added lines #L215 - L218 were not covered by tests

final EventWindowManager eventWindowManager = new DefaultEventWindowManager();

blocks.freezeCheckHolder()
.setFreezeCheckRef(instant ->
platformStateFacade.isInFreezePeriod(instant, swirldStateManager.getConsensusState()));
platformStateFacade.isInFreezePeriod(instant, stateLifecycleManager.getMutableState()));

Check warning on line 224 in platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/SwirldsPlatform.java#L224

Added line #L224 was not covered by tests

final AppNotifier appNotifier = new DefaultAppNotifier(blocks.notificationEngine());

Expand All @@ -231,7 +233,7 @@
this,
platformContext,
platformCoordinator,
swirldStateManager,
stateLifecycleManager,
savedStateController,
blocks.consensusStateEventHandler(),
blocks.reservedSignedStateResultPromise(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@
import com.swirlds.platform.reconnect.FallenBehindMonitor;
import com.swirlds.platform.scratchpad.Scratchpad;
import com.swirlds.platform.state.ConsensusStateEventHandler;
import com.swirlds.platform.state.SwirldStateManager;
import com.swirlds.platform.state.iss.IssScratchpad;
import com.swirlds.platform.state.service.PlatformStateFacade;
import com.swirlds.platform.state.signed.ReservedSignedState;
import com.swirlds.platform.system.Platform;
import com.swirlds.platform.wiring.PlatformComponents;
import com.swirlds.platform.wiring.PlatformWiring;
import com.swirlds.state.MerkleNodeState;
import com.swirlds.state.StateLifecycleManager;
import com.swirlds.state.merkle.StateLifecycleManagerImpl;
import com.swirlds.virtualmap.VirtualMap;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.io.IOException;
Expand Down Expand Up @@ -433,7 +434,9 @@
final ApplicationCallbacks callbacks =
new ApplicationCallbacks(preconsensusEventConsumer, snapshotOverrideConsumer, staleEventConsumer);

final SwirldStateManager swirldStateManager = new SwirldStateManager(platformContext, currentRoster);
@SuppressWarnings("unchecked")
final StateLifecycleManager stateLifecycleManager = new StateLifecycleManagerImpl(
platformContext.getMetrics(), platformContext.getTime(), createStateFromVirtualMap);

Check warning on line 439 in platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/builder/PlatformBuilder.java#L438-L439

Added lines #L438 - L439 were not covered by tests

if (model == null) {
final WiringConfig wiringConfig = platformContext.getConfiguration().getConfigData(WiringConfig.class);
Expand Down Expand Up @@ -495,7 +498,7 @@
issScratchpad,
NotificationEngine.buildEngine(getStaticThreadManager()),
new AtomicReference<>(),
swirldStateManager,
stateLifecycleManager,
new AtomicReference<>(),
firstPlatform,
consensusStateEventHandler,
Expand Down
Loading
Loading