diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/platform/event/EventMigrationTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/platform/event/EventMigrationTest.java index 35d47c10c80e..209c63c7b513 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/platform/event/EventMigrationTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/platform/event/EventMigrationTest.java @@ -17,7 +17,9 @@ package com.hedera.node.app.platform.event; import com.hedera.hapi.node.base.SemanticVersion; +import com.hedera.node.app.version.HederaSoftwareVersion; import com.hedera.node.app.version.ServicesSoftwareVersion; +import com.swirlds.common.constructable.ClassConstructorPair; import com.swirlds.common.constructable.ConstructableRegistry; import com.swirlds.common.constructable.ConstructableRegistryException; import com.swirlds.common.crypto.Hash; @@ -25,7 +27,9 @@ import com.swirlds.platform.event.hashing.DefaultEventHasher; import com.swirlds.platform.recovery.internal.EventStreamSingleFileIterator; import com.swirlds.platform.system.StaticSoftwareVersion; +import com.swirlds.platform.system.events.CesEvent; import com.swirlds.platform.system.events.EventDescriptorWrapper; +import com.swirlds.virtualmap.VirtualMap; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.File; import java.io.IOException; @@ -40,11 +44,17 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static com.swirlds.common.test.fixtures.ConfigurationUtils.configuration; + public class EventMigrationTest { @BeforeAll public static void setUp() throws ConstructableRegistryException { - ConstructableRegistry.getInstance().registerConstructables(""); + ConstructableRegistry registry = ConstructableRegistry.getInstance(); + registry.registerConstructable(new ClassConstructorPair(Hash.class, Hash::new)); + registry.registerConstructable(new ClassConstructorPair(CesEvent.class, CesEvent::new)); + registry.registerConstructable(new ClassConstructorPair(HederaSoftwareVersion.class, HederaSoftwareVersion::new)); + registry.registerConstructable(new ClassConstructorPair(VirtualMap.class, () -> new VirtualMap(configuration()))); StaticSoftwareVersion.setSoftwareVersion(new ServicesSoftwareVersion(SemanticVersion.DEFAULT, 0)); } diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/merkle/disk/OnDiskTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/merkle/disk/OnDiskTest.java index 0ce731b563b9..bd3526aaebca 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/merkle/disk/OnDiskTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/merkle/disk/OnDiskTest.java @@ -163,7 +163,7 @@ void populateTheMapAndFlushToDiskAndReadBack() throws IOException { // Before we can read the data back, we need to register the data types // I plan to deserialize. - final var r = new MerkleSchemaRegistry(registry, SERVICE_NAME, DEFAULT_CONFIG, new SchemaApplications()); + final var r = new MerkleSchemaRegistry(registry, SERVICE_NAME, configuration, new SchemaApplications()); r.register(schema); // read it back now as our map and validate the data come back fine diff --git a/platform-sdk/swirlds-common/src/testFixtures/java/com/swirlds/common/test/fixtures/ConfigurationUtils.java b/platform-sdk/swirlds-common/src/testFixtures/java/com/swirlds/common/test/fixtures/ConfigurationUtils.java index 464a12ab1331..850443699ff0 100644 --- a/platform-sdk/swirlds-common/src/testFixtures/java/com/swirlds/common/test/fixtures/ConfigurationUtils.java +++ b/platform-sdk/swirlds-common/src/testFixtures/java/com/swirlds/common/test/fixtures/ConfigurationUtils.java @@ -4,12 +4,14 @@ import com.swirlds.common.io.config.TemporaryFileConfig; import com.swirlds.config.api.Configuration; import com.swirlds.config.api.ConfigurationBuilder; +import com.swirlds.virtualmap.config.VirtualMapConfig; public class ConfigurationUtils { public static Configuration configuration() { return ConfigurationBuilder.create() .withConfigDataType(TemporaryFileConfig.class) .withConfigDataType(StateCommonConfig.class) + .withConfigDataType(VirtualMapConfig.class) .build(); } } diff --git a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/MerkleDbDataSourceBuilder.java b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/MerkleDbDataSourceBuilder.java index 825eb5c88383..1b5990c6fa36 100644 --- a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/MerkleDbDataSourceBuilder.java +++ b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/MerkleDbDataSourceBuilder.java @@ -16,10 +16,12 @@ package com.swirlds.merkledb; +import com.swirlds.common.constructable.ConstructableClass; import com.swirlds.common.io.streams.SerializableDataInputStream; import com.swirlds.common.io.streams.SerializableDataOutputStream; import com.swirlds.common.io.utility.LegacyTemporaryFileBuilder; import com.swirlds.config.api.Configuration; +import com.swirlds.merkledb.constructable.constructors.MerkleDbDataSourceBuilderConstructor; import com.swirlds.virtualmap.datasource.VirtualDataSource; import com.swirlds.virtualmap.datasource.VirtualDataSourceBuilder; import java.io.IOException; @@ -27,6 +29,8 @@ import java.nio.file.Path; import java.util.Objects; +import static com.swirlds.merkledb.MerkleDbDataSourceBuilder.CLASS_ID; + /** * Virtual data source builder that manages {@link MerkleDb} based data sources. * @@ -37,9 +41,10 @@ * between data sources with the same label, e.g. on copy or snapshot, MerkleDb builders * use different database directories, usually managed using {@link LegacyTemporaryFileBuilder}. */ +@ConstructableClass(value = CLASS_ID, constructorType = MerkleDbDataSourceBuilderConstructor.class) public class MerkleDbDataSourceBuilder implements VirtualDataSourceBuilder { - private static final long CLASS_ID = 0x176ede0e1a69828L; + public static final long CLASS_ID = 0x176ede0e1a69828L; private static final class ClassVersion { public static final int ORIGINAL = 1; @@ -62,7 +67,8 @@ private static final class ClassVersion { /** * Default constructor for deserialization purposes. */ - public MerkleDbDataSourceBuilder() { + public MerkleDbDataSourceBuilder(final Configuration configuration) { + this.configuration = configuration; // for deserialization } @@ -72,7 +78,7 @@ public MerkleDbDataSourceBuilder() { * @param tableConfig * Table configuration to use to create new data sources */ - public MerkleDbDataSourceBuilder(final MerkleDbTableConfig tableConfig, Configuration configuration) { + public MerkleDbDataSourceBuilder(final MerkleDbTableConfig tableConfig, final Configuration configuration) { this(null, tableConfig, configuration); } @@ -84,7 +90,7 @@ public MerkleDbDataSourceBuilder(final MerkleDbTableConfig tableConfig, Configur * @param tableConfig * Table configuration to use to create new data sources */ - public MerkleDbDataSourceBuilder(final Path databaseDir, final MerkleDbTableConfig tableConfig, Configuration configuration) { + public MerkleDbDataSourceBuilder(final Path databaseDir, final MerkleDbTableConfig tableConfig, final Configuration configuration) { this.databaseDir = databaseDir; this.tableConfig = tableConfig; this.configuration = configuration; diff --git a/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/constructable/constructors/MerkleDbDataSourceBuilderConstructor.java b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/constructable/constructors/MerkleDbDataSourceBuilderConstructor.java new file mode 100644 index 000000000000..1e1cd4816f0b --- /dev/null +++ b/platform-sdk/swirlds-merkledb/src/main/java/com/swirlds/merkledb/constructable/constructors/MerkleDbDataSourceBuilderConstructor.java @@ -0,0 +1,9 @@ +package com.swirlds.merkledb.constructable.constructors; + +import com.swirlds.config.api.Configuration; +import com.swirlds.merkledb.MerkleDbDataSourceBuilder; + +@FunctionalInterface +public interface MerkleDbDataSourceBuilderConstructor { + MerkleDbDataSourceBuilder create(final Configuration configuration); +} diff --git a/platform-sdk/swirlds-state-api/src/testFixtures/java/com/swirlds/state/test/fixtures/merkle/MerkleTestBase.java b/platform-sdk/swirlds-state-api/src/testFixtures/java/com/swirlds/state/test/fixtures/merkle/MerkleTestBase.java index 9467954cf9cc..85dac5e07f1a 100644 --- a/platform-sdk/swirlds-state-api/src/testFixtures/java/com/swirlds/state/test/fixtures/merkle/MerkleTestBase.java +++ b/platform-sdk/swirlds-state-api/src/testFixtures/java/com/swirlds/state/test/fixtures/merkle/MerkleTestBase.java @@ -21,6 +21,7 @@ import com.hedera.hapi.node.base.SemanticVersion; import com.hedera.pbj.runtime.Codec; import com.swirlds.common.config.StateCommonConfig; +import com.swirlds.common.constructable.ClassConstructorPair; import com.swirlds.common.constructable.ConstructableRegistry; import com.swirlds.common.constructable.ConstructableRegistryException; import com.swirlds.common.crypto.DigestType; @@ -49,14 +50,19 @@ import com.swirlds.state.test.fixtures.StateTestBase; import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.config.VirtualMapConfig; +import com.swirlds.virtualmap.internal.cache.VirtualNodeCache; +import com.swirlds.virtualmap.internal.merkle.VirtualMapState; +import com.swirlds.virtualmap.internal.merkle.VirtualRootNode; import com.swirlds.virtualmap.serialize.KeySerializer; import com.swirlds.virtualmap.serialize.ValueSerializer; import edu.umd.cs.findbugs.annotations.NonNull; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Path; import java.util.stream.Stream; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.provider.Arguments; @@ -85,6 +91,15 @@ */ public class MerkleTestBase extends StateTestBase { + public static Configuration configuration() { + return ConfigurationBuilder.create() + .withConfigDataType(VirtualMapConfig.class) + .withConfigDataType(MerkleDbConfig.class) + .withConfigDataType(TemporaryFileConfig.class) + .withConfigDataType(StateCommonConfig.class) + .build(); + } + protected Configuration configuration = ConfigurationBuilder.create() .withConfigDataType(VirtualMapConfig.class) .withConfigDataType(MerkleDbConfig.class) @@ -266,7 +281,11 @@ protected void setupConstructableRegistry() { registry.registerConstructables("com.swirlds.merklemap"); registry.registerConstructables("com.swirlds.merkledb"); registry.registerConstructables("com.swirlds.fcqueue"); - registry.registerConstructables("com.swirlds.virtualmap"); + registry.registerConstructable(new ClassConstructorPair(VirtualMap.class, () -> new VirtualMap(configuration()))); + registry.registerConstructable(new ClassConstructorPair(VirtualMapState.class, VirtualMapState::new)); + registry.registerConstructable(new ClassConstructorPair(VirtualRootNode.class, () -> new VirtualRootNode<>(configuration()))); + registry.registerConstructable(new ClassConstructorPair(VirtualNodeCache.class, () -> new VirtualNodeCache<>(configuration().getConfigData(VirtualMapConfig.class)))); + registry.registerConstructable(new ClassConstructorPair(MerkleDbDataSourceBuilder.class, () -> new MerkleDbDataSourceBuilder(configuration()))); registry.registerConstructables("com.swirlds.common.merkle"); registry.registerConstructables("com.swirlds.common"); registry.registerConstructables("com.swirlds.merkle"); diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/VirtualMap.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/VirtualMap.java index 806ebb133b74..498612810eb1 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/VirtualMap.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/VirtualMap.java @@ -173,7 +173,8 @@ private static final class ChildIndices { * Required by the {@link com.swirlds.common.constructable.RuntimeConstructable} contract. * This can only be called as part of serialization and reconnect, not for normal use. */ - public VirtualMap() { + public VirtualMap(Configuration configuration) { + this.configuration = configuration; registryRecord = RuntimeObjectRegistry.createRecord(getClass()); } @@ -192,7 +193,7 @@ public VirtualMap( final ValueSerializer valueSerializer, final VirtualDataSourceBuilder dataSourceBuilder, final Configuration configuration) { - this(); + this(configuration); this.configuration = configuration; setChild(ChildIndices.MAP_STATE_CHILD_INDEX, new VirtualMapState(Objects.requireNonNull(label))); setChild( @@ -207,8 +208,7 @@ public VirtualMap( * must not be null. */ private VirtualMap(final VirtualMap source) { - this(); - this.configuration = source.configuration; + this(source.configuration); setChild(ChildIndices.MAP_STATE_CHILD_INDEX, source.getState().copy()); setChild(ChildIndices.VIRTUAL_ROOT_CHILD_INDEX, source.getRoot().copy()); } diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualNodeCacheConstructor.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualNodeCacheConstructor.java new file mode 100644 index 000000000000..dc52c9aaca35 --- /dev/null +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualNodeCacheConstructor.java @@ -0,0 +1,10 @@ +package com.swirlds.virtualmap.constructable.constructors; + +import com.swirlds.virtualmap.config.VirtualMapConfig; +import com.swirlds.virtualmap.internal.cache.VirtualNodeCache; + +@FunctionalInterface +public interface VirtualNodeCacheConstructor { + VirtualNodeCache create(final VirtualMapConfig vmConfig); +} + diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualRootNodeConstructor.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualRootNodeConstructor.java new file mode 100644 index 000000000000..46f95a646f09 --- /dev/null +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/constructable/constructors/VirtualRootNodeConstructor.java @@ -0,0 +1,10 @@ +package com.swirlds.virtualmap.constructable.constructors; + +import com.swirlds.config.api.Configuration; +import com.swirlds.virtualmap.internal.merkle.VirtualRootNode; +import edu.umd.cs.findbugs.annotations.NonNull; + +@FunctionalInterface +public interface VirtualRootNodeConstructor { + VirtualRootNode create(final @NonNull Configuration configuration); +} diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/datasource/VirtualDataSourceBuilder.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/datasource/VirtualDataSourceBuilder.java index efd558f5b3c4..dab85f4ec195 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/datasource/VirtualDataSourceBuilder.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/datasource/VirtualDataSourceBuilder.java @@ -17,6 +17,8 @@ package com.swirlds.virtualmap.datasource; import com.swirlds.common.io.SelfSerializable; +import com.swirlds.config.api.Configuration; + import java.nio.file.Path; /** diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/cache/VirtualNodeCache.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/cache/VirtualNodeCache.java index bf11f94c0cdf..c4a322e44c2e 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/cache/VirtualNodeCache.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/cache/VirtualNodeCache.java @@ -18,9 +18,11 @@ import static com.swirlds.common.threading.manager.AdHocThreadManager.getStaticThreadManager; import static com.swirlds.logging.legacy.LogMarker.EXCEPTION; +import static com.swirlds.virtualmap.internal.cache.VirtualNodeCache.CLASS_ID; import com.swirlds.base.state.MutabilityException; import com.swirlds.common.FastCopyable; +import com.swirlds.common.constructable.ConstructableClass; import com.swirlds.common.crypto.Hash; import com.swirlds.common.exceptions.PlatformException; import com.swirlds.common.io.SelfSerializable; @@ -32,6 +34,7 @@ import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.VirtualValue; import com.swirlds.virtualmap.config.VirtualMapConfig; +import com.swirlds.virtualmap.constructable.constructors.VirtualNodeCacheConstructor; import com.swirlds.virtualmap.datasource.VirtualHashRecord; import com.swirlds.virtualmap.datasource.VirtualLeafRecord; import java.io.IOException; @@ -112,12 +115,14 @@ * @param * The type of value used for leaves */ +@ConstructableClass(value = CLASS_ID, constructorType = VirtualNodeCacheConstructor.class) public final class VirtualNodeCache implements FastCopyable, SelfSerializable { private static final Logger logger = LogManager.getLogger(VirtualNodeCache.class); - private static final long CLASS_ID = 0x493743f0ace96d2cL; + @SuppressWarnings("ProtectedMemberInFinalClass") + public static final long CLASS_ID = 0x493743f0ace96d2cL; private static final class ClassVersion { public static final int ORIGINAL = 1; diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/merkle/VirtualRootNode.java b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/merkle/VirtualRootNode.java index e5c98d6a0eb8..2e4f80897cff 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/merkle/VirtualRootNode.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/com/swirlds/virtualmap/internal/merkle/VirtualRootNode.java @@ -34,10 +34,12 @@ import static com.swirlds.virtualmap.internal.Path.getSiblingPath; import static com.swirlds.virtualmap.internal.Path.isFarRight; import static com.swirlds.virtualmap.internal.Path.isLeft; +import static com.swirlds.virtualmap.internal.merkle.VirtualMapState.CLASS_ID; import static com.swirlds.virtualmap.internal.merkle.VirtualMapState.MAX_LABEL_LENGTH; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; +import com.swirlds.common.constructable.ConstructableClass; import com.swirlds.common.crypto.DigestType; import com.swirlds.common.crypto.Hash; import com.swirlds.common.io.ExternalSelfSerializable; @@ -64,6 +66,7 @@ import com.swirlds.virtualmap.VirtualValue; import com.swirlds.virtualmap.config.VirtualMapConfig; import com.swirlds.virtualmap.config.VirtualMapReconnectMode; +import com.swirlds.virtualmap.constructable.constructors.VirtualRootNodeConstructor; import com.swirlds.virtualmap.datasource.VirtualDataSource; import com.swirlds.virtualmap.datasource.VirtualDataSourceBuilder; import com.swirlds.virtualmap.datasource.VirtualHashRecord; @@ -135,6 +138,7 @@ * The value */ @DebugIterationEndpoint +@ConstructableClass(value = CLASS_ID, constructorType = VirtualRootNodeConstructor.class) public final class VirtualRootNode extends PartialBinaryMerkleInternal implements CustomReconnectRoot, ExternalSelfSerializable, VirtualRoot, MerkleInternal { @@ -354,7 +358,7 @@ public static class ClassVersion { * Creates a new empty root node. This constructor is used for deserialization and * reconnects, not for normal use. */ - public VirtualRootNode(Configuration configuration) { + public VirtualRootNode(final @NonNull Configuration configuration) { this.fastCopyVersion = 0; // Hasher is required during reconnects this.hasher = new VirtualHasher<>(); diff --git a/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java b/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java index b48388e87a5d..39bb16a98c3e 100644 --- a/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java +++ b/platform-sdk/swirlds-virtualmap/src/main/java/module-info.java @@ -13,7 +13,7 @@ exports com.swirlds.virtualmap.internal to com.swirlds.virtualmap.test.fixtures; exports com.swirlds.virtualmap.internal.cache to - com.swirlds.virtualmap.test.fixtures; + com.swirlds.virtualmap.test.fixtures, com.swirlds.common, com.swirlds.state.api.test.fixtures; requires transitive com.swirlds.common; requires transitive com.swirlds.config.api;