Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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 @@ -43,7 +43,7 @@
*/
public HederaVirtualMapState(
@NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time) {
super(configuration, metrics, time);
super(configuration, metrics);
}

/**
Expand All @@ -55,7 +55,7 @@
*/
public HederaVirtualMapState(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
super(virtualMap, metrics, time);
super(virtualMap, metrics);

Check warning on line 58 in hedera-node/hedera-app/src/main/java/com/hedera/node/app/HederaVirtualMapState.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hedera-app/src/main/java/com/hedera/node/app/HederaVirtualMapState.java#L58

Added line #L58 was not covered by tests
}

protected HederaVirtualMapState(@NonNull final HederaVirtualMapState from) {
Expand All @@ -70,14 +70,6 @@
return new HederaVirtualMapState(this);
}

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

@Override
public String getInfoJson() {
final JSONObject rootJson = new JSONObject();
Expand Down Expand Up @@ -138,4 +130,9 @@

return rootJson.toString();
}

@Override
public String toString() {
return "HederaVirtualMapState[round=%d]".formatted(DEFAULT_PLATFORM_STATE_FACADE.roundOf(this));

Check warning on line 136 in hedera-node/hedera-app/src/main/java/com/hedera/node/app/HederaVirtualMapState.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hedera-app/src/main/java/com/hedera/node/app/HederaVirtualMapState.java#L136

Added line #L136 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ private void forceFlush(ReadableKVState<?, ?> state) {

if (vm.size() > 1) {
vm.enableFlush();
vm.release();
if (vm.getReservationCount() > 0) {
vm.release();
}
vm.waitUntilFlushed();
}
} catch (IllegalAccessException | NoSuchFieldException | InterruptedException e) {
Expand Down Expand Up @@ -218,17 +220,17 @@ void snapshot() throws IOException {
* After it gets saved to disk again, and then loaded back in, it results in ClassCastException due to incorrect classId.
*/
@Test
void dualReadAndWrite() throws IOException, ConstructableRegistryException {
void dualReadAndWrite() throws IOException {
final Schema<SemanticVersion> schemaV1 = createV1Schema();
final StateLifecycleManager stateLifecycleManager = createStateLifecycleManager(schemaV1);
final MerkleNodeState originalTree = stateLifecycleManager.getMutableState();

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,4 @@ public long queueElementPath(final int stateId, @NonNull final Bytes expectedVal
public void initializeState(@NonNull final StateMetadata<?, ?> md) {
// do nothing
}

@Override
public long getRound() {
return 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
package org.hiero.otter.fixtures.app;

import static com.swirlds.platform.state.service.PlatformStateFacade.DEFAULT_PLATFORM_STATE_FACADE;
import static org.hiero.otter.fixtures.app.state.OtterStateInitializer.initOtterAppState;

import com.hedera.hapi.node.base.SemanticVersion;
Expand All @@ -23,12 +22,12 @@ public class OtterAppState extends VirtualMapState<OtterAppState> implements Mer

public OtterAppState(
@NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time) {
super(configuration, metrics, time);
super(configuration, metrics);
}

public OtterAppState(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
super(virtualMap, metrics, time);
super(virtualMap, metrics);
}

/**
Expand Down Expand Up @@ -82,14 +81,6 @@ protected OtterAppState copyingConstructor() {
return new OtterAppState(this);
}

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

/**
* Commit the state of all services.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static com.swirlds.demo.consistency.V0680ConsistencyTestingToolSchema.STATE_LONG_STATE_ID;
import static com.swirlds.logging.legacy.LogMarker.EXCEPTION;
import static com.swirlds.logging.legacy.LogMarker.STARTUP;
import static com.swirlds.platform.state.service.PlatformStateFacade.DEFAULT_PLATFORM_STATE_FACADE;
import static org.hiero.base.utility.ByteUtils.byteArrayToLong;
import static org.hiero.base.utility.NonCryptographicHashing.hash64;

Expand Down Expand Up @@ -84,7 +83,7 @@

public ConsistencyTestingToolState(
@NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time) {
super(configuration, metrics, time);
super(configuration, metrics);

Check warning on line 86 in platform-sdk/platform-apps/tests/ConsistencyTestingTool/src/main/java/com/swirlds/demo/consistency/ConsistencyTestingToolState.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/platform-apps/tests/ConsistencyTestingTool/src/main/java/com/swirlds/demo/consistency/ConsistencyTestingToolState.java#L86

Added line #L86 was not covered by tests
transactionHandlingHistory = new TransactionHandlingHistory();
transactionsAwaitingPostHandle = ConcurrentHashMap.newKeySet();
logger.info(STARTUP.getMarker(), "New State Constructed.");
Expand All @@ -95,7 +94,7 @@
*/
public ConsistencyTestingToolState(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
super(virtualMap, metrics, time);
super(virtualMap, metrics);
transactionHandlingHistory = new TransactionHandlingHistory();
transactionsAwaitingPostHandle = ConcurrentHashMap.newKeySet();
logger.info(STARTUP.getMarker(), "New State Constructed.");
Expand Down Expand Up @@ -150,14 +149,6 @@
transactionHandlingHistory.init(logFilePath);
}

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

/**
* @return the number of rounds handled
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import static com.swirlds.demo.iss.V0680ISSTestingToolSchema.PLANNED_ISS_LIST_STATE_ID;
import static com.swirlds.demo.iss.V0680ISSTestingToolSchema.PLANNED_LOG_ERROR_LIST_STATE_ID;
import static com.swirlds.demo.iss.V0680ISSTestingToolSchema.RUNNING_SUM_STATE_ID;
import static com.swirlds.platform.state.service.PlatformStateFacade.DEFAULT_PLATFORM_STATE_FACADE;

import com.hedera.hapi.node.state.primitives.ProtoLong;
import com.hedera.hapi.node.state.primitives.ProtoString;
Expand Down Expand Up @@ -74,12 +73,12 @@

public ISSTestingToolState(
@NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time) {
super(configuration, metrics, time);
super(configuration, metrics);

Check warning on line 76 in platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java#L76

Added line #L76 was not covered by tests
}

public ISSTestingToolState(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
super(virtualMap, metrics, time);
super(virtualMap, metrics);
}

/**
Expand Down Expand Up @@ -187,12 +186,4 @@
List<PlannedLogError> getPlannedLogErrorList() {
return plannedLogErrorList;
}

/**
* {@inheritDoc}
*/
@Override
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
package com.swirlds.demo.migration;

import static com.swirlds.platform.state.service.PlatformStateFacade.DEFAULT_PLATFORM_STATE_FACADE;

import com.swirlds.base.time.Time;
import com.swirlds.config.api.Configuration;
import com.swirlds.metrics.api.Metrics;
Expand All @@ -15,12 +13,12 @@

public MigrationTestingToolState(
@NonNull final Configuration configuration, @NonNull final Metrics metrics, @NonNull final Time time) {
super(configuration, metrics, time);
super(configuration, metrics);

Check warning on line 16 in platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java#L16

Added line #L16 was not covered by tests
}

public MigrationTestingToolState(
@NonNull final VirtualMap virtualMap, @NonNull final Metrics metrics, @NonNull final Time time) {
super(virtualMap, metrics, time);
super(virtualMap, metrics);

Check warning on line 21 in platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java#L21

Added line #L21 was not covered by tests
}

private MigrationTestingToolState(final MigrationTestingToolState that) {
Expand All @@ -31,12 +29,4 @@
protected MigrationTestingToolState copyingConstructor() {
return new MigrationTestingToolState(this);
}

/**
* {@inheritDoc}
*/
@Override
public long getRound() {
return DEFAULT_PLATFORM_STATE_FACADE.roundOf(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ private MerkleTreeSnapshotWriter() {
* @param targetPath the {@link Path} to write the snapshot to
*/
public static void createSnapshot(
@NonNull final MerkleNode merkleRoot, @NonNull final Path targetPath, long round) {
logger.info(STATE_TO_DISK.getMarker(), "Creating a snapshot on demand in {} for round {}", targetPath, round);
@NonNull final MerkleNode merkleRoot, @NonNull final Path targetPath, @NonNull final String rootInfo) {
logger.info(STATE_TO_DISK.getMarker(), "Creating a snapshot on demand in {} for {}", targetPath, rootInfo);
try {
writeMerkleRootToFile(targetPath, merkleRoot);
logger.info(
STATE_TO_DISK.getMarker(),
"Successfully created a snapshot on demand in {} for round {}",
"Successfully created a snapshot on demand in {} for {}",
targetPath,
round);
rootInfo);
} catch (final Throwable e) {
logger.error(
EXCEPTION.getMarker(),
"Unable to write a snapshot on demand for round {} to {}.",
round,
"Unable to write a snapshot on demand for {} to {}.",
rootInfo,
targetPath,
e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class DefaultSavedStateController implements SavedStateController {
/**
* Constructor
*
* @param platformContext the platform context*
* @param platformContext the platform context
*/
public DefaultSavedStateController(@NonNull final PlatformContext platformContext) {
this.stateConfig = platformContext.getConfiguration().getConfigData(StateConfig.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ void sequenceOfStatesTest(final boolean startAtGenesis) throws IOException {
.build();
final ReservedSignedState reservedSignedState = signedState.reserve("initialTestReservation");

initLifecycleManagerAndMakeStateImmutable(reservedSignedState.get());
initLifecycleManagerAndMakeStateImmutable(reservedSignedState.get(), round != firstRound);
controller.markSavedState(new StateWithHashComplexity(reservedSignedState, 1));
hashState(signedState);

Expand Down Expand Up @@ -382,7 +382,7 @@ void stateDeletionTest() throws IOException {
.resolve("node" + SELF_ID + "_round" + fatalRound);
final SignedState fatalState =
new RandomSignedStateGenerator(random).setRound(fatalRound).build();
initLifecycleManagerAndMakeStateImmutable(fatalState);
initLifecycleManagerAndMakeStateImmutable(fatalState, true);
hashState(fatalState);
fatalState.markAsStateToSave(FATAL_ERROR);
manager.dumpStateTask(StateDumpRequest.create(fatalState.reserve("test")));
Expand All @@ -395,7 +395,7 @@ void stateDeletionTest() throws IOException {
new RandomSignedStateGenerator(random).setRound(round).build();
issState.markAsStateToSave(PERIODIC_SNAPSHOT);
states.add(signedState);
initLifecycleManagerAndMakeStateImmutable(signedState);
initLifecycleManagerAndMakeStateImmutable(signedState, true);
hashState(signedState);
manager.saveStateTask(signedState.reserve("test"));

Expand Down Expand Up @@ -430,6 +430,15 @@ static void hashState(SignedState signedState) {
}

void initLifecycleManagerAndMakeStateImmutable(SignedState state) {
initLifecycleManagerAndMakeStateImmutable(state, false);
}

void initLifecycleManagerAndMakeStateImmutable(SignedState state, boolean createNewStateLifecycleManager) {
if (createNewStateLifecycleManager) {
stateLifecycleManager =
new StateLifecycleManagerImpl(context.getMetrics(), context.getTime(), TestVirtualMapState::new);
}

stateLifecycleManager.initState(state.getState(), false);
stateLifecycleManager.getMutableState().release();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,26 @@ void initStateRejectsImmutableInput() {
assertThrows(MutabilityException.class, () -> stateLifecycleManager.initState(immutable, false));
}

@Test
@DisplayName("getMutableState() throws if not initialized")
void getMutableStateThrowsIfNotInitialized() {
final PlatformContext platformContext =
TestPlatformContextBuilder.create().build();
final StateLifecycleManager uninitialized = new StateLifecycleManagerImpl(
platformContext.getMetrics(), platformContext.getTime(), TestVirtualMapState::new);
assertThrows(IllegalStateException.class, uninitialized::getMutableState);
}

@Test
@DisplayName("getLatestImmutableState() throws if not initialized")
void getLatestImmutableStateThrowsIfNotInitialized() {
final PlatformContext platformContext =
TestPlatformContextBuilder.create().build();
final StateLifecycleManager uninitialized = new StateLifecycleManagerImpl(
platformContext.getMetrics(), platformContext.getTime(), TestVirtualMapState::new);
assertThrows(IllegalStateException.class, uninitialized::getLatestImmutableState);
}

private static MerkleNodeState newState(PlatformStateFacade platformStateFacade) {
final String virtualMapLabel =
StateLifecycleManagerTests.class.getSimpleName() + "-" + java.util.UUID.randomUUID();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ default MerkleNode getRoot() {
return (MerkleNode) this;
}

/**
* Retrieves the round number associated with this state.
*
* @return a round number of the state.
*/
long getRound();

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
* <li>Creating a mutable copy of the state, while making the current mutable state immutable.</li>
* </ul>
*
* An implementation of this class must be thread-safe.
*
*/
public interface StateLifecycleManager {

Expand All @@ -27,13 +25,18 @@ public interface StateLifecycleManager {

/**
* Get the mutable state. Consecutive calls to this method may return different instances,
* if this method is not called on the one and the only thread that is calling {@link #copyMutableState}
* if this method is not called on the one and the only thread that is calling {@link #copyMutableState}.
* If a parallel thread calls {@link #copyMutableState}, the returned object will become immutable and
* on the subsequent call of {@link #copyMutableState} it will be destroyed.
*
* @return the mutable state.
*/
MerkleNodeState getMutableState();

/**
* Get the latest immutable state. Consecutive calls to this method may return different instances,
* if this method is not called on the one and the only thread that is calling {@link #copyMutableState}
* If a parallel thread calls {@link #copyMutableState}, the returned object will become destroyed.
* @return the latest immutable state.
*/
MerkleNodeState getLatestImmutableState();
Expand Down
Loading
Loading