diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoFeeAccumulator.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoFeeAccumulator.java index 8b4113fabb80..ba754e9607ca 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoFeeAccumulator.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoFeeAccumulator.java @@ -20,7 +20,7 @@ import com.hedera.hapi.node.base.Timestamp; import com.hedera.hapi.node.transaction.Query; import com.hedera.node.app.hapi.utils.fee.FeeObject; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.mono.context.primitives.StateView; import com.hedera.node.app.service.mono.fees.calculation.UsageBasedFeeCalculator; import com.hedera.node.app.service.mono.fees.calculation.UsagePricesProvider; diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoGetTopicInfoUsage.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoGetTopicInfoUsage.java index 01ca619ae1ab..1948fb965a06 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoGetTopicInfoUsage.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/fees/MonoGetTopicInfoUsage.java @@ -21,7 +21,7 @@ import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.mono.fees.calculation.consensus.queries.GetTopicInfoResourceUsage; import com.hedera.node.app.service.mono.legacy.core.jproto.JKey; import com.hedera.node.app.service.mono.pbj.PbjConverter; diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactory.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactory.java index f60ce4583bbb..f998558ba06a 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactory.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactory.java @@ -21,7 +21,8 @@ import com.hedera.node.app.service.admin.FreezeService; import com.hedera.node.app.service.admin.impl.ReadableSpecialFileStore; import com.hedera.node.app.service.consensus.ConsensusService; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.impl.ReadableTopicStoreImpl; import com.hedera.node.app.service.schedule.ScheduleService; import com.hedera.node.app.service.schedule.impl.ReadableScheduleStore; import com.hedera.node.app.service.token.ReadableAccountStore; @@ -50,7 +51,7 @@ public class ReadableStoreFactory { AccountAccess.class, new StoreEntry(TokenService.NAME, ReadableAccountStoreImpl::new), ReadableAccountStore.class, new StoreEntry(TokenService.NAME, ReadableAccountStoreImpl::new), ReadableTokenStore.class, new StoreEntry(TokenService.NAME, ReadableTokenStoreImpl::new), - ReadableTopicStore.class, new StoreEntry(ConsensusService.NAME, ReadableTopicStore::new), + ReadableTopicStore.class, new StoreEntry(ConsensusService.NAME, ReadableTopicStoreImpl::new), ReadableScheduleStore.class, new StoreEntry(ScheduleService.NAME, ReadableScheduleStore::new), ReadableSpecialFileStore.class, new StoreEntry(FreezeService.NAME, ReadableSpecialFileStore::new)); diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/TransactionDispatcher.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/TransactionDispatcher.java index d7bf0eb19e04..88cc5b6c4f81 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/TransactionDispatcher.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/dispatcher/TransactionDispatcher.java @@ -24,7 +24,6 @@ import com.hedera.hapi.node.consensus.ConsensusUpdateTopicTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.admin.impl.ReadableSpecialFileStore; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.config.ConsensusServiceConfig; import com.hedera.node.app.service.consensus.impl.records.ConsensusCreateTopicRecordBuilder; @@ -123,11 +122,11 @@ public void dispatchPreHandle(@NonNull final PreHandleContext context) throws Pr case CONSENSUS_CREATE_TOPIC -> handlers.consensusCreateTopicHandler() .preHandle(context); case CONSENSUS_UPDATE_TOPIC -> handlers.consensusUpdateTopicHandler() - .preHandle(context, context.createStore(ReadableTopicStore.class)); + .preHandle(context); case CONSENSUS_DELETE_TOPIC -> handlers.consensusDeleteTopicHandler() - .preHandle(context, context.createStore(ReadableTopicStore.class)); + .preHandle(context); case CONSENSUS_SUBMIT_MESSAGE -> handlers.consensusSubmitMessageHandler() - .preHandle(context, context.createStore(ReadableTopicStore.class)); + .preHandle(context); case CONTRACT_CREATE_INSTANCE -> handlers.contractCreateHandler().preHandle(context); case CONTRACT_UPDATE_INSTANCE -> handlers.contractUpdateHandler().preHandle(context); diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/AdaptedMonoFeeCalculator.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/AdaptedMonoFeeCalculator.java index 3c4abfc8edbe..bc864e8d1ecf 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/AdaptedMonoFeeCalculator.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/AdaptedMonoFeeCalculator.java @@ -22,7 +22,7 @@ import com.hedera.node.app.fees.MonoGetTopicInfoUsage; import com.hedera.node.app.hapi.utils.exception.InvalidTxBodyException; import com.hedera.node.app.hapi.utils.fee.FeeObject; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.mono.context.primitives.StateView; import com.hedera.node.app.service.mono.fees.FeeCalculator; import com.hedera.node.app.service.mono.fees.HbarCentExchange; diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoFeeAccumulatorTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoFeeAccumulatorTest.java index a497bfdcdcf4..46d3c636ade9 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoFeeAccumulatorTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoFeeAccumulatorTest.java @@ -26,7 +26,7 @@ import com.hedera.hapi.node.base.Timestamp; import com.hedera.hapi.node.transaction.Query; import com.hedera.node.app.hapi.utils.fee.FeeObject; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.mono.context.primitives.StateView; import com.hedera.node.app.service.mono.fees.calculation.UsageBasedFeeCalculator; import com.hedera.node.app.service.mono.fees.calculation.UsagePricesProvider; diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoGetTopicInfoUsageTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoGetTopicInfoUsageTest.java index 00a509f65090..15e9d591221e 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoGetTopicInfoUsageTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/fees/MonoGetTopicInfoUsageTest.java @@ -27,7 +27,7 @@ import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.consensus.ConsensusGetTopicInfoQuery; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.mono.fees.calculation.consensus.queries.GetTopicInfoResourceUsage; import com.hedera.node.app.service.mono.legacy.core.jproto.JKey; import com.hedera.node.app.service.mono.pbj.PbjConverter; diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/MonoTransactionDispatcherTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/MonoTransactionDispatcherTest.java index 639df8d7f228..ef8ff0549eee 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/MonoTransactionDispatcherTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/MonoTransactionDispatcherTest.java @@ -581,6 +581,32 @@ void testPreHandleDispatch( private static Stream getDispatchParameters() { return Stream.of( + // consensus + Arguments.of( + TransactionBody.newBuilder() + .consensusCreateTopic(ConsensusCreateTopicTransactionBody.DEFAULT) + .build(), + (Function) + TransactionHandlers::consensusCreateTopicHandler), + Arguments.of( + TransactionBody.newBuilder() + .consensusUpdateTopic(ConsensusUpdateTopicTransactionBody.DEFAULT) + .build(), + (Function) + TransactionHandlers::consensusUpdateTopicHandler), + Arguments.of( + TransactionBody.newBuilder() + .consensusDeleteTopic(ConsensusDeleteTopicTransactionBody.DEFAULT) + .build(), + (Function) + TransactionHandlers::consensusDeleteTopicHandler), + Arguments.of( + TransactionBody.newBuilder() + .consensusSubmitMessage(ConsensusSubmitMessageTransactionBody.DEFAULT) + .build(), + (Function) + TransactionHandlers::consensusSubmitMessageHandler), + // crypto Arguments.of( TransactionBody.newBuilder() @@ -729,32 +755,6 @@ void testPreHandleWithPayer(final TransactionBody txBody, final DispatchToHandle private static Stream getDispatchParametersOld() { return Stream.of( - // consensus - Arguments.of( - TransactionBody.newBuilder() - .consensusCreateTopic(ConsensusCreateTopicTransactionBody.DEFAULT) - .build(), - (DispatchToHandler) (handlers, meta) -> - verify(handlers.consensusCreateTopicHandler()).preHandle(meta)), - Arguments.of( - TransactionBody.newBuilder() - .consensusUpdateTopic(ConsensusUpdateTopicTransactionBody.DEFAULT) - .build(), - (DispatchToHandler) (handlers, meta) -> - verify(handlers.consensusUpdateTopicHandler()).preHandle(eq(meta), any())), - Arguments.of( - TransactionBody.newBuilder() - .consensusDeleteTopic(ConsensusDeleteTopicTransactionBody.DEFAULT) - .build(), - (DispatchToHandler) (handlers, meta) -> - verify(handlers.consensusDeleteTopicHandler()).preHandle(eq(meta), any())), - Arguments.of( - TransactionBody.newBuilder() - .consensusSubmitMessage(ConsensusSubmitMessageTransactionBody.DEFAULT) - .build(), - (DispatchToHandler) (handlers, meta) -> - verify(handlers.consensusSubmitMessageHandler()).preHandle(eq(meta), any())), - // contract Arguments.of( TransactionBody.newBuilder() diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactoryTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactoryTest.java index c9e18ebd0136..eaa3ae52bcd2 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactoryTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/dispatcher/ReadableStoreFactoryTest.java @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.BDDMockito.given; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.spi.state.ReadableStates; import com.hedera.node.app.state.HederaState; import org.junit.jupiter.api.BeforeEach; diff --git a/hedera-node/hedera-consensus-service-impl/build.gradle.kts b/hedera-node/hedera-consensus-service-impl/build.gradle.kts index 708d0be053c2..6dbdee538308 100644 --- a/hedera-node/hedera-consensus-service-impl/build.gradle.kts +++ b/hedera-node/hedera-consensus-service-impl/build.gradle.kts @@ -39,5 +39,6 @@ dependencies { testImplementation(testLibs.bundles.testing) testImplementation(testFixtures(project(":hedera-node:hedera-mono-service"))) testImplementation(testFixtures(project(":hedera-node:hedera-app-spi"))) + testImplementation(project(":hedera-node:hedera-token-service")) testImplementation(testLibs.mockito.inline) } diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStore.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStoreImpl.java similarity index 81% rename from hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStore.java rename to hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStoreImpl.java index ae1960e6a9bc..de7d0faf4c13 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStore.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/ReadableTopicStoreImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC + * Copyright (C) 2023 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.state.consensus.Topic; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.TopicMetadata; import com.hedera.node.app.service.mono.utils.EntityNum; import com.hedera.node.app.spi.state.ReadableKVState; import com.hedera.node.app.spi.state.ReadableStates; @@ -34,16 +36,16 @@ * *

This class is not exported from the module. It is an internal implementation detail. */ -public class ReadableTopicStore extends TopicStore { +public class ReadableTopicStoreImpl extends TopicStore implements ReadableTopicStore { /** The underlying data storage class that holds the topic data. */ private final ReadableKVState topicState; /** - * Create a new {@link ReadableTopicStore} instance. + * Create a new {@link ReadableTopicStoreImpl} instance. * * @param states The state to use. */ - public ReadableTopicStore(@NonNull final ReadableStates states) { + public ReadableTopicStoreImpl(@NonNull final ReadableStates states) { requireNonNull(states); this.topicState = states.get("TOPICS"); @@ -57,12 +59,14 @@ public ReadableTopicStore(@NonNull final ReadableStates states) { * @return topic's metadata */ // TODO : Change to return Topic instead of TopicMetadata + @Nullable public TopicMetadata getTopicMetadata(@Nullable final TopicID id) { final var topic = getTopicLeaf(id); return topic.map(TopicStore::topicMetaFrom).orElse(null); } - public Optional getTopicLeaf(TopicID id) { + @NonNull + public Optional getTopicLeaf(@NonNull final TopicID id) { return Optional.ofNullable(Objects.requireNonNull(topicState).get(EntityNum.fromTopicId(id))); } } diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/TopicStore.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/TopicStore.java index a0a000fa5e9c..0bfe70af53cd 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/TopicStore.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/TopicStore.java @@ -21,6 +21,8 @@ import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.base.Timestamp; import com.hedera.hapi.node.state.consensus.Topic; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.TopicMetadata; import java.util.Optional; import java.util.OptionalLong; @@ -44,32 +46,4 @@ public static TopicMetadata topicMetaFrom(final Topic topic) { topic.topicNumber(), topic.deleted()); } - - // TODO : Remove use of TopicMetadata and change to use Topic instead - - /** - * Topic metadata - * - * @param memo topic's memo - * @param adminKey topic's admin key - * @param submitKey topic's submit key - * @param autoRenewDurationSeconds topic's auto-renew duration in seconds - * @param autoRenewAccountId topic's auto-renew account id - * @param expirationTimestamp topic's expiration timestamp - * @param sequenceNumber topic's sequence number - * @param runningHash topic's running hash - * @param key topic's key - * @param isDeleted topic's deleted flag - */ - public record TopicMetadata( - Optional memo, - Key adminKey, - Key submitKey, - long autoRenewDurationSeconds, - OptionalLong autoRenewAccountId, - Timestamp expirationTimestamp, - long sequenceNumber, - byte[] runningHash, - long key, - boolean isDeleted) {} } diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusCreateTopicHandler.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusCreateTopicHandler.java index 02c3ca480790..5d50c5de0b04 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusCreateTopicHandler.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusCreateTopicHandler.java @@ -29,7 +29,6 @@ import com.hedera.hapi.node.base.HederaFunctionality; import com.hedera.hapi.node.consensus.ConsensusCreateTopicTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.config.ConsensusServiceConfig; import com.hedera.node.app.service.consensus.impl.records.ConsensusCreateTopicRecordBuilder; @@ -55,19 +54,7 @@ public ConsensusCreateTopicHandler() { // Exists for injection } - /** - * This method is called during the pre-handle workflow. - * - *

Typically, this method validates the {@link TransactionBody} semantically, gathers all - * required keys, and warms the cache. - * - *

Please note: the method signature is just a placeholder which is most likely going to - * change. - * - * @param context the {@link PreHandleContext} which collects all information that will be - * passed to the handle stage - * @throws NullPointerException if one of the arguments is {@code null} - */ + @Override public void preHandle(@NonNull final PreHandleContext context) throws PreCheckException { requireNonNull(context); final var op = context.body().consensusCreateTopicOrThrow(); diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusDeleteTopicHandler.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusDeleteTopicHandler.java index dc255e5fdb5f..69da5dcd6522 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusDeleteTopicHandler.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusDeleteTopicHandler.java @@ -25,7 +25,7 @@ import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.consensus.ConsensusDeleteTopicTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.records.ConsensusDeleteTopicRecordBuilder; import com.hedera.node.app.service.consensus.impl.records.DeleteTopicRecordBuilder; @@ -47,22 +47,12 @@ public ConsensusDeleteTopicHandler() { // Exists for injection } - /** - * This method is called during the pre-handle workflow. - * - *

Determines signatures needed for deleting a consensus topic - * - * @param context the {@link PreHandleContext} which collects all information that will be - * passed to {@code handle()} - * @param topicStore the {@link ReadableTopicStore} to use to resolve topic metadata - * @throws NullPointerException if any of the arguments are {@code null} - */ - public void preHandle(@NonNull final PreHandleContext context, @NonNull ReadableTopicStore topicStore) - throws PreCheckException { + @Override + public void preHandle(@NonNull final PreHandleContext context) throws PreCheckException { requireNonNull(context); - requireNonNull(topicStore); final var op = context.body().consensusDeleteTopicOrThrow(); + final var topicStore = context.createStore(ReadableTopicStore.class); // The topic ID must be present on the transaction and the topic must exist. final var topic = topicStore.getTopicMetadata(op.topicID()); mustExist(topic, INVALID_TOPIC_ID); diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusGetTopicInfoHandler.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusGetTopicInfoHandler.java index 4fb62acf0ddd..ca3b806868b8 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusGetTopicInfoHandler.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusGetTopicInfoHandler.java @@ -37,7 +37,7 @@ import com.hedera.hapi.node.consensus.ConsensusTopicInfo; import com.hedera.hapi.node.transaction.Query; import com.hedera.hapi.node.transaction.Response; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.spi.info.NetworkInfo; import com.hedera.node.app.spi.workflows.PaidQueryHandler; import com.hedera.node.app.spi.workflows.PreCheckException; diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusSubmitMessageHandler.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusSubmitMessageHandler.java index 873778487034..9427e417ed04 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusSubmitMessageHandler.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusSubmitMessageHandler.java @@ -34,7 +34,7 @@ import com.hedera.hapi.node.consensus.ConsensusSubmitMessageTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; import com.hedera.hapi.node.transaction.TransactionBody; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.config.ConsensusServiceConfig; import com.hedera.node.app.service.consensus.impl.records.ConsensusSubmitMessageRecordBuilder; @@ -67,22 +67,12 @@ public ConsensusSubmitMessageHandler() { // Exists for injection } - /** - * This method is called during the pre-handle workflow. - * - *

Determines signatures needed for submitting a new message to a consensus topic - * - * @param context the {@link PreHandleContext} which collects all information that will be - * passed to {@code handle()} - * @param topicStore the {@link ReadableTopicStore} to use to resolve topic metadata - * @throws NullPointerException if one of the arguments is {@code null} - */ - public void preHandle(@NonNull final PreHandleContext context, @NonNull ReadableTopicStore topicStore) - throws PreCheckException { + @Override + public void preHandle(@NonNull final PreHandleContext context) throws PreCheckException { requireNonNull(context); - requireNonNull(topicStore); final var op = context.body().consensusSubmitMessageOrThrow(); + final var topicStore = context.createStore(ReadableTopicStore.class); // The topic ID must be present on the transaction and the topic must exist. final var topic = topicStore.getTopicMetadata(op.topicID()); mustExist(topic, INVALID_TOPIC_ID); diff --git a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusUpdateTopicHandler.java b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusUpdateTopicHandler.java index c4aa50235148..11cb330ed7a6 100644 --- a/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusUpdateTopicHandler.java +++ b/hedera-node/hedera-consensus-service-impl/src/main/java/com/hedera/node/app/service/consensus/impl/handlers/ConsensusUpdateTopicHandler.java @@ -29,8 +29,7 @@ import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.consensus.ConsensusUpdateTopicTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.hapi.node.transaction.TransactionBody; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.records.ConsensusUpdateTopicRecordBuilder; import com.hedera.node.app.service.consensus.impl.records.UpdateTopicRecordBuilder; @@ -55,23 +54,11 @@ public ConsensusUpdateTopicHandler() { // Exists for injection } - /** - * This method is called during the pre-handle workflow. - * - *

Typically, this method validates the {@link TransactionBody} semantically, gathers all - * required keys, and warms the cache. - * - *

Please note: the method signature is just a placeholder which is most likely going to - * change. - * - * @param context the {@link PreHandleContext} which collects all information that will be - * passed to {@code #handle()} - * @throws NullPointerException if one of the arguments is {@code null} - */ - public void preHandle(@NonNull final PreHandleContext context, @NonNull ReadableTopicStore topicStore) - throws PreCheckException { + @Override + public void preHandle(@NonNull final PreHandleContext context) throws PreCheckException { requireNonNull(context); final var op = context.body().consensusUpdateTopicOrThrow(); + final var topicStore = context.createStore(ReadableTopicStore.class); // The topic ID must be present on the transaction and the topic must exist. final var topic = topicStore.getTopicMetadata(op.topicID()); diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreImplTest.java similarity index 89% rename from hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreTest.java rename to hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreImplTest.java index 8c8e15e15ea5..fd63f6778af5 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/ReadableTopicStoreImplTest.java @@ -24,7 +24,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.given; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.impl.ReadableTopicStoreImpl; import com.hedera.node.app.service.consensus.impl.test.handlers.ConsensusHandlerTestBase; import com.hedera.node.app.service.mono.state.merkle.MerkleTopic; import com.hedera.node.app.service.mono.utils.EntityNum; @@ -35,12 +36,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -class ReadableTopicStoreTest extends ConsensusHandlerTestBase { +class ReadableTopicStoreImplTest extends ConsensusHandlerTestBase { private ReadableTopicStore subject; @BeforeEach void setUp() { - subject = new ReadableTopicStore(readableStates); + subject = new ReadableTopicStoreImpl(readableStates); } @Test @@ -67,8 +68,8 @@ void getsTopicMetadataIfTopicExistsWithNoAutoRenewAccount() throws PreCheckExcep readableTopicState = readableTopicState(); given(readableStates.get(TOPICS)) .willReturn(readableTopicState); - readableStore = new ReadableTopicStore(readableStates); - subject = new ReadableTopicStore(readableStates); + readableStore = new ReadableTopicStoreImpl(readableStates); + subject = new ReadableTopicStoreImpl(readableStates); final var topicMeta = subject.getTopicMetadata(WELL_KNOWN_TOPIC_ID); @@ -91,19 +92,19 @@ void missingTopicIsNull() { final var state = MapReadableKVState.builder("TOPICS").build(); given(readableStates.get(TOPICS)).willReturn(state); - subject = new ReadableTopicStore(readableStates); + subject = new ReadableTopicStoreImpl(readableStates); assertThat(subject.getTopicMetadata(WELL_KNOWN_TOPIC_ID)).isNull(); } @Test void constructorCreatesTopicState() { - final var store = new ReadableTopicStore(readableStates); + final var store = new ReadableTopicStoreImpl(readableStates); assertNotNull(store); } @Test void nullArgsFail() { - assertThrows(NullPointerException.class, () -> new ReadableTopicStore(null)); + assertThrows(NullPointerException.class, () -> new ReadableTopicStoreImpl(null)); } } diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/AdapterUtils.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/AdapterUtils.java index 1104f33b6e81..785a0f8366eb 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/AdapterUtils.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/AdapterUtils.java @@ -22,7 +22,42 @@ import static com.hedera.node.app.service.mono.utils.EntityNum.MISSING_NUM; import static com.hedera.node.app.service.mono.utils.EntityNum.fromAccountId; import static com.hedera.node.app.service.mono.utils.MiscUtils.asKeyUnchecked; -import static com.hedera.test.factories.scenarios.TxnHandlingScenario.*; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.COMPLEX_KEY_ACCOUNT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.COMPLEX_KEY_ACCOUNT_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.CURRENTLY_UNUSED_ALIAS; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.CUSTOM_PAYER_ACCOUNT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.CUSTOM_PAYER_ACCOUNT_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DEFAULT_BALANCE; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DEFAULT_PAYER_BALANCE; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DELEGATING_SPENDER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DELEGATING_SPENDER_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DILIGENT_SIGNING_PAYER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.DILIGENT_SIGNING_PAYER_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.FIRST_TOKEN_SENDER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.FIRST_TOKEN_SENDER_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.FIRST_TOKEN_SENDER_LITERAL_ALIAS; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.FROM_OVERLAP_PAYER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.FROM_OVERLAP_PAYER_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.KNOWN_TOKEN_NO_SPECIAL_KEYS; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.KNOWN_TOKEN_WITH_WIPE; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.MISC_ACCOUNT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.MISC_ACCOUNT_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.NO_RECEIVER_SIG; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.NO_RECEIVER_SIG_ALIAS; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.NO_RECEIVER_SIG_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.OWNER_ACCOUNT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.OWNER_ACCOUNT_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.RECEIVER_SIG; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.RECEIVER_SIG_ALIAS; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.RECEIVER_SIG_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.SECOND_TOKEN_SENDER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.SECOND_TOKEN_SENDER_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.SYS_ACCOUNT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.SYS_ACCOUNT_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.TOKEN_RECEIVER; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.TOKEN_TREASURY; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.TOKEN_TREASURY_KT; +import static com.hedera.test.factories.scenarios.TxnHandlingScenario.TOKEN_WIPE_KT; import static com.hedera.test.factories.txns.SignedTxnFactory.DEFAULT_NODE; import static com.hedera.test.factories.txns.SignedTxnFactory.DEFAULT_PAYER; import static com.hedera.test.factories.txns.SignedTxnFactory.DEFAULT_PAYER_KT; @@ -39,7 +74,7 @@ import com.hedera.hapi.node.state.token.AccountTokenAllowance; import com.hedera.node.app.service.mono.state.virtual.EntityNumValue; import com.hedera.node.app.service.mono.state.virtual.EntityNumVirtualKey; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; import com.hedera.node.app.spi.fixtures.state.MapReadableKVState; import com.hedera.node.app.spi.state.ReadableKVState; import com.hedera.node.app.spi.state.ReadableStates; @@ -66,13 +101,13 @@ private AdapterUtils() { } /** - * Returns the {@link AccountAccess} containing the "well-known" accounts and aliases that + * Returns the {@link ReadableAccountStore} containing the "well-known" accounts and aliases that * exist in a {@code SigRequirementsTest} scenario. This allows us to re-use these scenarios in - * unit tests that require an {@link AccountAccess}. + * unit tests that require an {@link ReadableAccountStore}. * * @return the well-known account store */ - public static AccountAccess wellKnownKeyLookupAt() { + public static ReadableAccountStore wellKnownKeyLookupAt() { return new TestFixturesKeyLookup(mockStates(Map.of( ALIASES_KEY, wellKnownAliasState(), ACCOUNTS_KEY, wellKnownAccountsState()))); diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerParityTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerParityTest.java index 208a12294ef9..aee7e1dd8621 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerParityTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerParityTest.java @@ -28,20 +28,20 @@ import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.node.app.service.consensus.impl.handlers.ConsensusCreateTopicHandler; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; +import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.workflows.PreCheckException; -import com.hedera.node.app.spi.workflows.PreHandleContext; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class ConsensusCreateTopicHandlerParityTest { private final ConsensusCreateTopicHandler subject = new ConsensusCreateTopicHandler(); - private AccountAccess keyLookup; + private ReadableAccountStore accountStore; @BeforeEach void setUp() { - keyLookup = AdapterUtils.wellKnownKeyLookupAt(); + accountStore = AdapterUtils.wellKnownKeyLookupAt(); } @Test @@ -50,7 +50,7 @@ void getsConsensusCreateTopicNoAdminKeyOrAutoRenewAccount() throws PreCheckExcep final var txn = CONSENSUS_CREATE_TOPIC_NO_ADDITIONAL_KEYS_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); subject.preHandle(context); // then: @@ -64,7 +64,7 @@ void getsConsensusCreateTopicAdminKey() throws PreCheckException { final var txn = CONSENSUS_CREATE_TOPIC_ADMIN_KEY_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); subject.preHandle(context); // then: @@ -79,7 +79,7 @@ void getsConsensusCreateTopicAdminKeyAndAutoRenewAccount() throws PreCheckExcept final var txn = CONSENSUS_CREATE_TOPIC_ADMIN_KEY_AND_AUTORENEW_ACCOUNT_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); subject.preHandle(context); // then: @@ -94,7 +94,7 @@ void getsConsensusCreateTopicAdminKeyAndAutoRenewAccountAsPayerWithCustomPayer() final var txn = CONSENSUS_CREATE_TOPIC_ADMIN_KEY_AND_AUTORENEW_ACCOUNT_AS_PAYER_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); subject.preHandle(context); // then: @@ -112,7 +112,7 @@ void invalidAutoRenewAccountOnConsensusCreateTopicThrows() throws PreCheckExcept final var txn = CONSENSUS_CREATE_TOPIC_MISSING_AUTORENEW_ACCOUNT_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); assertThrowsPreCheck(() -> subject.preHandle(context), ResponseCodeEnum.INVALID_AUTORENEW_ACCOUNT); } @@ -122,7 +122,7 @@ void invalidAutoRenewAccountOnConsensusCreateTopicThrowsWithCustomPayer() throws final var txn = CONSENSUS_CREATE_TOPIC_MISSING_AUTORENEW_ACCOUNT_SCENARIO.pbjTxnBody(); // when: - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); assertThrowsPreCheck(() -> subject.preHandle(context), ResponseCodeEnum.INVALID_AUTORENEW_ACCOUNT); } } diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerTest.java index 8a23bda14c97..3c2298e85bd6 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusCreateTopicHandlerTest.java @@ -47,14 +47,14 @@ import com.hedera.node.app.service.consensus.impl.records.ConsensusCreateTopicRecordBuilder; import com.hedera.node.app.service.consensus.impl.records.CreateTopicRecordBuilder; import com.hedera.node.app.service.mono.utils.EntityNum; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; +import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.meta.HandleContext; import com.hedera.node.app.spi.validation.AttributeValidator; import com.hedera.node.app.spi.validation.ExpiryMeta; import com.hedera.node.app.spi.validation.ExpiryValidator; import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.PreCheckException; -import com.hedera.node.app.spi.workflows.PreHandleContext; import java.time.Instant; import java.util.Set; import org.junit.jupiter.api.BeforeEach; @@ -71,7 +71,7 @@ class ConsensusCreateTopicHandlerTest extends ConsensusHandlerTestBase { AccountID.newBuilder().accountNum(4L).build(); @Mock - private AccountAccess accountAccess; + private ReadableAccountStore accountStore; @Mock private HandleContext handleContext; @@ -125,7 +125,7 @@ void nonNullKeyInputsRequired() throws PreCheckException { final var submitKey = SIMPLE_KEY_B; // when: - final var context = new PreHandleContext(accountAccess, newCreateTxn(adminKey, submitKey, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(adminKey, submitKey, false)); subject.preHandle(context); // then: @@ -141,7 +141,7 @@ void differentAdminKey() throws PreCheckException { final var adminKey = SIMPLE_KEY_A; // when: - final var context = new PreHandleContext(accountAccess, newCreateTxn(adminKey, null, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(adminKey, null, false)); subject.preHandle(context); // then: @@ -157,7 +157,7 @@ void createAddsDifferentSubmitKey() throws PreCheckException { final var submitKey = SIMPLE_KEY_B; // when: - final var context = new PreHandleContext(accountAccess, newCreateTxn(null, submitKey, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(null, submitKey, false)); subject.preHandle(context); // then: @@ -173,7 +173,7 @@ void createAddsPayerAsAdmin() throws PreCheckException { final var payerKey = mockPayerLookup(protoPayerKey); // when: - final var context = new PreHandleContext(accountAccess, newCreateTxn(protoPayerKey, null, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(protoPayerKey, null, false)); subject.preHandle(context); // then: @@ -189,7 +189,7 @@ void createAddsPayerAsSubmitter() throws PreCheckException { final var payerKey = mockPayerLookup(protoPayerKey); // when: - final var context = new PreHandleContext(accountAccess, newCreateTxn(null, protoPayerKey, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(null, protoPayerKey, false)); subject.preHandle(context); // then: @@ -202,7 +202,7 @@ void autoAccountKeyIsNull() throws PreCheckException { // given: mockPayerLookup(); final var acct1234 = AccountID.newBuilder().accountNum(1234).build(); - given(accountAccess.getAccountById(acct1234)).willReturn(null); + given(accountStore.getAccountById(acct1234)).willReturn(null); final var inputTxn = TransactionBody.newBuilder() .transactionID( TransactionID.newBuilder().accountID(ACCOUNT_ID_3).build()) @@ -212,7 +212,7 @@ void autoAccountKeyIsNull() throws PreCheckException { .build(); // when: - final var context = new PreHandleContext(accountAccess, inputTxn); + final var context = new FakePreHandleContext(accountStore, inputTxn); assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_AUTORENEW_ACCOUNT); } @@ -221,7 +221,7 @@ void autoAccountKeyIsNull() throws PreCheckException { void requiresPayerKey() throws PreCheckException { // given: final var payerKey = mockPayerLookup(); - final var context = new PreHandleContext(accountAccess, newCreateTxn(null, null, false)); + final var context = new FakePreHandleContext(accountStore, newCreateTxn(null, null, false)); // when: subject.preHandle(context); @@ -421,7 +421,7 @@ private Key mockPayerLookup() throws PreCheckException { private Key mockPayerLookup(Key key) throws PreCheckException { final var account = mock(Account.class); given(account.key()).willReturn(key); - given(accountAccess.getAccountById(ACCOUNT_ID_3)).willReturn(account); + given(accountStore.getAccountById(ACCOUNT_ID_3)).willReturn(account); return key; } } diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusDeleteTopicHandlerTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusDeleteTopicHandlerTest.java index 40dd4051c8b9..5f8597c4c73a 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusDeleteTopicHandlerTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusDeleteTopicHandlerTest.java @@ -45,15 +45,15 @@ import com.hedera.hapi.node.consensus.ConsensusDeleteTopicTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; import com.hedera.hapi.node.transaction.TransactionBody; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.handlers.ConsensusDeleteTopicHandler; import com.hedera.node.app.service.consensus.impl.records.ConsensusDeleteTopicRecordBuilder; import com.hedera.node.app.service.mono.utils.EntityNum; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; +import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.PreCheckException; -import com.hedera.node.app.spi.workflows.PreHandleContext; import com.hedera.pbj.runtime.io.buffer.Bytes; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -61,19 +61,22 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class ConsensusDeleteTopicHandlerTest extends ConsensusHandlerTestBase { - private AccountAccess keyLookup; + + @Mock + private ReadableAccountStore accountStore; + + @Mock private ReadableTopicStore mockStore; private ConsensusDeleteTopicHandler subject; @BeforeEach void setUp() { - keyLookup = mock(AccountAccess.class); - mockStore = mock(ReadableTopicStore.class); subject = new ConsensusDeleteTopicHandler(); writableTopicState = writableTopicStateWithOneKey(); @@ -87,10 +90,11 @@ void adminKeySigRequired() throws PreCheckException { // given: final var payerKey = mockPayerLookup(); mockTopicLookup(SIMPLE_KEY_A, null); - final var context = new PreHandleContext(keyLookup, newDeleteTxn()); + final var context = new FakePreHandleContext(accountStore, newDeleteTxn()); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - subject.preHandle(context, mockStore); + subject.preHandle(context); // then: assertThat(context.payerKey()).isEqualTo(payerKey); @@ -109,10 +113,11 @@ void submitKeyNotRequired() throws PreCheckException { // given: final var payerKey = mockPayerLookup(); mockTopicLookup(SIMPLE_KEY_A, SIMPLE_KEY_B); - final var context = new PreHandleContext(keyLookup, newDeleteTxn()); + final var context = new FakePreHandleContext(accountStore, newDeleteTxn()); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - subject.preHandle(context, mockStore); + subject.preHandle(context); // then: assertThat(context.payerKey()).isEqualTo(payerKey); @@ -126,10 +131,11 @@ void topicIdNotFound() throws PreCheckException { // given: mockPayerLookup(); given(mockStore.getTopicMetadata(notNull())).willReturn(null); - final var context = new PreHandleContext(keyLookup, newDeleteTxn()); + final var context = new FakePreHandleContext(accountStore, newDeleteTxn()); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - assertThrowsPreCheck(() -> subject.preHandle(context, mockStore), INVALID_TOPIC_ID); + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_TOPIC_ID); } @Test @@ -138,10 +144,11 @@ void noTopicAdminKey() throws PreCheckException { // given: mockPayerLookup(); mockTopicLookup(null, SIMPLE_KEY_A); - final var context = new PreHandleContext(keyLookup, newDeleteTxn()); + final var context = new FakePreHandleContext(accountStore, newDeleteTxn()); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - assertThrowsPreCheck(() -> subject.preHandle(context, mockStore), UNAUTHORIZED); + assertThrowsPreCheck(() -> subject.preHandle(context), UNAUTHORIZED); } @Test @@ -205,7 +212,7 @@ class ConsensusDeleteTopicHandlerParityTest { @BeforeEach void setUp() { mockStore = mock(ReadableTopicStore.class); - keyLookup = AdapterUtils.wellKnownKeyLookupAt(); + accountStore = AdapterUtils.wellKnownKeyLookupAt(); } @Test @@ -215,10 +222,11 @@ void getsConsensusDeleteTopicNoAdminKey() throws PreCheckException { var topicMeta = newTopicMeta(null, A_NONNULL_KEY); // any submit key that isn't null given(mockStore.getTopicMetadata(notNull())).willReturn(topicMeta); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - assertThrowsPreCheck(() -> subject.preHandle(context, mockStore), UNAUTHORIZED); + assertThrowsPreCheck(() -> subject.preHandle(context), UNAUTHORIZED); } @Test @@ -227,10 +235,11 @@ void getsConsensusDeleteTopicWithAdminKey() throws Throwable { final var txn = CONSENSUS_DELETE_TOPIC_SCENARIO.pbjTxnBody(); var topicMeta = newTopicMeta(MISC_TOPIC_ADMIN_KT.asPbjKey(), null); // any submit key given(mockStore.getTopicMetadata(notNull())).willReturn(topicMeta); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - subject.preHandle(context, mockStore); + subject.preHandle(context); // then: assertDefaultPayer(context); @@ -242,15 +251,16 @@ void reportsConsensusDeleteTopicMissingTopic() throws PreCheckException { // given: final var txn = CONSENSUS_DELETE_TOPIC_MISSING_TOPIC_SCENARIO.pbjTxnBody(); given(mockStore.getTopicMetadata(notNull())).willReturn(null); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, mockStore); // when: - assertThrowsPreCheck(() -> subject.preHandle(context, mockStore), INVALID_TOPIC_ID); + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_TOPIC_ID); } } private Key mockPayerLookup() throws PreCheckException { - return ConsensusTestUtils.mockPayerLookup(A_COMPLEX_KEY, PARITY_DEFAULT_PAYER, keyLookup); + return ConsensusTestUtils.mockPayerLookup(A_COMPLEX_KEY, PARITY_DEFAULT_PAYER, accountStore); } private void mockTopicLookup(final Key adminKey, final Key submitKey) throws PreCheckException { diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusGetTopicInfoHandlerTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusGetTopicInfoHandlerTest.java index 17134d5886b4..872f1d21510a 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusGetTopicInfoHandlerTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusGetTopicInfoHandlerTest.java @@ -41,7 +41,8 @@ import com.hedera.hapi.node.state.consensus.Topic; import com.hedera.hapi.node.transaction.Query; import com.hedera.hapi.node.transaction.Response; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.impl.ReadableTopicStoreImpl; import com.hedera.node.app.service.consensus.impl.handlers.ConsensusGetTopicInfoHandler; import com.hedera.node.app.service.mono.state.merkle.MerkleTopic; import com.hedera.node.app.service.mono.utils.EntityNum; @@ -126,7 +127,7 @@ void validatesQueryIfInvalidTopic() throws Throwable { final var state = MapReadableKVState.builder("TOPICS").build(); given(readableStates.get(TOPICS)).willReturn(state); - final var store = new ReadableTopicStore(readableStates); + final var store = new ReadableTopicStoreImpl(readableStates); final var query = createGetTopicInfoQuery(topicEntityNum.intValue()); when(context.query()).thenReturn(query); @@ -142,7 +143,7 @@ void validatesQueryIfDeletedTopic() throws Throwable { givenValidTopic(autoRenewId.accountNum(), true); readableTopicState = readableTopicState(); given(readableStates.get(TOPICS)).willReturn(readableTopicState); - readableStore = new ReadableTopicStore(readableStates); + readableStore = new ReadableTopicStoreImpl(readableStates); final var query = createGetTopicInfoQuery(topicEntityNum.intValue()); when(context.query()).thenReturn(query); diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusHandlerTestBase.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusHandlerTestBase.java index 45aa7788be55..bd83f5507e66 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusHandlerTestBase.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusHandlerTestBase.java @@ -28,7 +28,8 @@ import com.hedera.hapi.node.base.Timestamp; import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.state.consensus.Topic; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.impl.ReadableTopicStoreImpl; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.mono.utils.EntityNum; import com.hedera.node.app.spi.fixtures.state.MapReadableKVState; @@ -100,7 +101,7 @@ protected void refreshStoresWithCurrentTopicOnlyInReadable() { writableTopicState = emptyWritableTopicState(); given(readableStates.get(TOPICS)).willReturn(readableTopicState); given(writableStates.get(TOPICS)).willReturn(writableTopicState); - readableStore = new ReadableTopicStore(readableStates); + readableStore = new ReadableTopicStoreImpl(readableStates); writableStore = new WritableTopicStore(writableStates); } @@ -109,7 +110,7 @@ protected void refreshStoresWithCurrentTopicInBothReadableAndWritable() { writableTopicState = writableTopicStateWithOneKey(); given(readableStates.get(TOPICS)).willReturn(readableTopicState); given(writableStates.get(TOPICS)).willReturn(writableTopicState); - readableStore = new ReadableTopicStore(readableStates); + readableStore = new ReadableTopicStoreImpl(readableStates); writableStore = new WritableTopicStore(writableStates); } diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusSubmitMessageHandlerTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusSubmitMessageHandlerTest.java index bc3d1bf6c7dc..56944179ffa9 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusSubmitMessageHandlerTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusSubmitMessageHandlerTest.java @@ -22,7 +22,6 @@ import static com.hedera.node.app.service.consensus.impl.test.handlers.ConsensusCreateTopicHandlerTest.ACCOUNT_ID_3; import static com.hedera.node.app.service.consensus.impl.test.handlers.ConsensusTestUtils.SIMPLE_KEY_A; import static com.hedera.node.app.service.consensus.impl.test.handlers.ConsensusTestUtils.assertDefaultPayer; -import static com.hedera.node.app.service.consensus.impl.test.handlers.ConsensusTestUtils.newTopicMeta; import static com.hedera.node.app.service.mono.pbj.PbjConverter.asBytes; import static com.hedera.node.app.service.mono.state.merkle.MerkleTopic.RUNNING_HASH_VERSION; import static com.hedera.node.app.service.mono.utils.EntityNum.MISSING_NUM; @@ -50,17 +49,19 @@ import com.hedera.hapi.node.consensus.ConsensusSubmitMessageTransactionBody; import com.hedera.hapi.node.state.consensus.Topic; import com.hedera.hapi.node.transaction.TransactionBody; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.TopicMetadata; +import com.hedera.node.app.service.consensus.impl.ReadableTopicStoreImpl; import com.hedera.node.app.service.consensus.impl.WritableTopicStore; import com.hedera.node.app.service.consensus.impl.config.ConsensusServiceConfig; import com.hedera.node.app.service.consensus.impl.handlers.ConsensusSubmitMessageHandler; import com.hedera.node.app.service.consensus.impl.records.ConsensusSubmitMessageRecordBuilder; import com.hedera.node.app.service.mono.utils.EntityNum; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; +import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.meta.HandleContext; import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.PreCheckException; -import com.hedera.node.app.spi.workflows.PreHandleContext; import com.hedera.pbj.runtime.io.buffer.Bytes; import com.hedera.test.utils.TxnUtils; import java.time.Instant; @@ -77,7 +78,7 @@ @ExtendWith(MockitoExtension.class) class ConsensusSubmitMessageHandlerTest extends ConsensusHandlerTestBase { @Mock - private AccountAccess keyLookup; + private ReadableAccountStore accountStore; @Mock private HandleContext handleContext; @@ -95,7 +96,7 @@ void setUp() { writableTopicState = writableTopicStateWithOneKey(); given(readableStates.get(TOPICS)).willReturn(readableTopicState); given(writableStates.get(TOPICS)).willReturn(writableTopicState); - readableStore = new ReadableTopicStore(readableStates); + readableStore = new ReadableTopicStoreImpl(readableStates); writableStore = new WritableTopicStore(writableStates); } @@ -106,10 +107,11 @@ void submissionKeySigRequired() throws PreCheckException { // given: final var payerKey = mockPayerLookup(); mockTopicLookup(SIMPLE_KEY_A); - final var context = new PreHandleContext(keyLookup, newDefaultSubmitMessageTxn(topicEntityNum)); + final var context = new FakePreHandleContext(accountStore, newDefaultSubmitMessageTxn(topicEntityNum)); + context.registerStore(ReadableTopicStore.class, readableStore); // when: - subject.preHandle(context, readableStore); + subject.preHandle(context); // then: assertThat(context.payerKey()).isEqualTo(payerKey); @@ -123,10 +125,11 @@ void topicIdNotFound() throws PreCheckException { mockPayerLookup(); readableTopicState = emptyReadableTopicState(); given(readableStates.get(TOPICS)).willReturn(readableTopicState); - readableStore = new ReadableTopicStore(readableStates); - final var context = new PreHandleContext(keyLookup, newDefaultSubmitMessageTxn(topicEntityNum)); + readableStore = new ReadableTopicStoreImpl(readableStates); + final var context = new FakePreHandleContext(accountStore, newDefaultSubmitMessageTxn(topicEntityNum)); + context.registerStore(ReadableTopicStore.class, readableStore); - assertThrowsPreCheck(() -> subject.preHandle(context, readableStore), INVALID_TOPIC_ID); + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_TOPIC_ID); } @Test @@ -135,10 +138,11 @@ void noTopicSubmitKey() throws PreCheckException { readableStore = mock(ReadableTopicStore.class); mockPayerLookup(); mockTopicLookup(null); - final var context = new PreHandleContext(keyLookup, newDefaultSubmitMessageTxn(topicEntityNum)); + final var context = new FakePreHandleContext(accountStore, newDefaultSubmitMessageTxn(topicEntityNum)); + context.registerStore(ReadableTopicStore.class, readableStore); // when: - assertDoesNotThrow(() -> subject.preHandle(context, readableStore)); + assertDoesNotThrow(() -> subject.preHandle(context)); } @Nested @@ -146,7 +150,7 @@ class ConsensusSubmitMessageHandlerParityTest { @BeforeEach void setUp() { readableStore = mock(ReadableTopicStore.class); - keyLookup = AdapterUtils.wellKnownKeyLookupAt(); + accountStore = AdapterUtils.wellKnownKeyLookupAt(); } @Test @@ -155,10 +159,11 @@ void getsConsensusSubmitMessageNoSubmitKey() throws PreCheckException { var topicMeta = newTopicMeta(null); given(readableStore.getTopicMetadata(notNull())).willReturn(topicMeta); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, readableStore); // when: - subject.preHandle(context, readableStore); + subject.preHandle(context); // then: assertDefaultPayer(context); @@ -172,10 +177,11 @@ void getsConsensusSubmitMessageWithSubmitKey() throws PreCheckException { var topicMeta = newTopicMeta(key); given(readableStore.getTopicMetadata(notNull())).willReturn(topicMeta); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, readableStore); // when: - subject.preHandle(context, readableStore); + subject.preHandle(context); // then: ConsensusTestUtils.assertDefaultPayer(context); @@ -188,10 +194,11 @@ void reportsConsensusSubmitMessageMissingTopic() throws PreCheckException { final var txn = CONSENSUS_SUBMIT_MESSAGE_MISSING_TOPIC_SCENARIO.pbjTxnBody(); given(readableStore.getTopicMetadata(notNull())).willReturn(null); - final var context = new PreHandleContext(keyLookup, txn); + final var context = new FakePreHandleContext(accountStore, txn); + context.registerStore(ReadableTopicStore.class, readableStore); // when: - assertThrowsPreCheck(() -> subject.preHandle(context, readableStore), INVALID_TOPIC_ID); + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_TOPIC_ID); } } @@ -350,14 +357,14 @@ void failsIfChunkTxnPayerIsNotInitialID() { /* ----------------- Helper Methods ------------------- */ private Key mockPayerLookup() throws PreCheckException { - return ConsensusTestUtils.mockPayerLookup(A_COMPLEX_KEY, PARITY_DEFAULT_PAYER, keyLookup); + return ConsensusTestUtils.mockPayerLookup(A_COMPLEX_KEY, PARITY_DEFAULT_PAYER, accountStore); } private void mockTopicLookup(Key submitKey) throws PreCheckException { ConsensusTestUtils.mockTopicLookup(null, submitKey, readableStore); } - private static ReadableTopicStore.TopicMetadata newTopicMeta(Key submit) { + private static TopicMetadata newTopicMeta(Key submit) { return ConsensusTestUtils.newTopicMeta(null, submit); } diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusTestUtils.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusTestUtils.java index 46a1cd30df1c..d109cae35f56 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusTestUtils.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusTestUtils.java @@ -26,8 +26,9 @@ import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.state.token.Account; -import com.hedera.node.app.service.consensus.impl.ReadableTopicStore; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.consensus.ReadableTopicStore; +import com.hedera.node.app.service.consensus.TopicMetadata; +import com.hedera.node.app.service.token.ReadableAccountStore; import com.hedera.node.app.spi.workflows.PreCheckException; import com.hedera.node.app.spi.workflows.PreHandleContext; import com.hedera.pbj.runtime.io.buffer.Bytes; @@ -50,9 +51,9 @@ private ConsensusTestUtils() { throw new UnsupportedOperationException("Utility class"); } - static Key mockPayerLookup(Key key, AccountID accountId, AccountAccess keyLookup) throws PreCheckException { + static Key mockPayerLookup(Key key, AccountID accountId, ReadableAccountStore accountStore) { final var account = mock(Account.class); - given(keyLookup.getAccountById(accountId)).willReturn(account); + given(accountStore.getAccountById(accountId)).willReturn(account); given(account.key()).willReturn(key); return key; } @@ -74,8 +75,8 @@ static void mockTopicLookup(Key adminKey, Key submitKey, ReadableTopicStore topi .willReturn(newTopicMeta(adminKey != null ? adminKey : null, submitKey != null ? submitKey : null)); } - static ReadableTopicStore.TopicMetadata newTopicMeta(Key admin, Key submit) { - return new ReadableTopicStore.TopicMetadata( + static TopicMetadata newTopicMeta(Key admin, Key submit) { + return new TopicMetadata( Optional.of(Instant.now() + ""), admin, submit, diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusUpdateTopicHandlerTest.java b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusUpdateTopicHandlerTest.java index c69e0af4f398..2fd13d29425c 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusUpdateTopicHandlerTest.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/com/hedera/node/app/service/consensus/impl/test/handlers/ConsensusUpdateTopicHandlerTest.java @@ -38,16 +38,17 @@ import com.hedera.hapi.node.consensus.ConsensusUpdateTopicTransactionBody; import com.hedera.hapi.node.state.token.Account; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.consensus.ReadableTopicStore; import com.hedera.node.app.service.consensus.impl.handlers.ConsensusUpdateTopicHandler; import com.hedera.node.app.service.consensus.impl.records.ConsensusUpdateTopicRecordBuilder; -import com.hedera.node.app.spi.accounts.AccountAccess; +import com.hedera.node.app.service.token.ReadableAccountStore; +import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.meta.HandleContext; import com.hedera.node.app.spi.validation.AttributeValidator; import com.hedera.node.app.spi.validation.ExpiryMeta; import com.hedera.node.app.spi.validation.ExpiryValidator; import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.PreCheckException; -import com.hedera.node.app.spi.workflows.PreHandleContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -68,7 +69,7 @@ class ConsensusUpdateTopicHandlerTest extends ConsensusHandlerTestBase { private HandleContext handleContext; @Mock - private AccountAccess accountAccess; + private ReadableAccountStore accountStore; @Mock private Account account; @@ -387,7 +388,7 @@ void expiryMutationIsExpiry() { @Test void noneOfFieldsSetHaveNoRequiredKeys() throws PreCheckException { - given(accountAccess.getAccountById(payerId)).willReturn(account); + given(accountStore.getAccountById(payerId)).willReturn(account); given(account.key()).willReturn(adminKey); final var op = OP_BUILDER @@ -396,9 +397,10 @@ void noneOfFieldsSetHaveNoRequiredKeys() throws PreCheckException { .topicNum(topicEntityNum.longValue()) .build()) .build(); - final var context = new PreHandleContext(accountAccess, txnWith(op)); + final var context = new FakePreHandleContext(accountStore, txnWith(op)); + context.registerStore(ReadableTopicStore.class, readableStore); - subject.preHandle(context, readableStore); + subject.preHandle(context); assertThat(context.payerKey()).isEqualTo(adminKey); assertThat(context.requiredNonPayerKeys()).isEmpty(); @@ -406,28 +408,30 @@ void noneOfFieldsSetHaveNoRequiredKeys() throws PreCheckException { @Test void missingTopicFails() throws PreCheckException { - given(accountAccess.getAccountById(payerId)).willReturn(account); + given(accountStore.getAccountById(payerId)).willReturn(account); given(account.key()).willReturn(adminKey); final var op = OP_BUILDER.topicID(TopicID.newBuilder().topicNum(123L).build()).build(); - final var context = new PreHandleContext(accountAccess, txnWith(op)); + final var context = new FakePreHandleContext(accountStore, txnWith(op)); + context.registerStore(ReadableTopicStore.class, readableStore); - assertThrowsPreCheck(() -> subject.preHandle(context, readableStore), INVALID_TOPIC_ID); + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_TOPIC_ID); } @Test void adminKeyAndOpAdminKeyAdded() throws PreCheckException { - given(accountAccess.getAccountById(payerId)).willReturn(account); + given(accountStore.getAccountById(payerId)).willReturn(account); given(account.key()).willReturn(adminKey); final var op = OP_BUILDER .adminKey(anotherKey) .topicID(TopicID.newBuilder().topicNum(1L).build()) .build(); - final var context = new PreHandleContext(accountAccess, txnWith(op)); + final var context = new FakePreHandleContext(accountStore, txnWith(op)); + context.registerStore(ReadableTopicStore.class, readableStore); - subject.preHandle(context, readableStore); + subject.preHandle(context); assertThat(context.payerKey()).isEqualTo(adminKey); // adminKey is same as payer key. So will not be added to required keys. @@ -438,18 +442,19 @@ void adminKeyAndOpAdminKeyAdded() throws PreCheckException { @Test void autoRenewAccountKeyAdded() throws PreCheckException { - given(accountAccess.getAccountById(autoRenewId)).willReturn(autoRenewAccount); + given(accountStore.getAccountById(autoRenewId)).willReturn(autoRenewAccount); given(autoRenewAccount.key()).willReturn(autoRenewKey); - given(accountAccess.getAccountById(payerId)).willReturn(account); + given(accountStore.getAccountById(payerId)).willReturn(account); given(account.key()).willReturn(adminKey); final var op = OP_BUILDER .autoRenewAccount(autoRenewId) .topicID(WELL_KNOWN_TOPIC_ID) .build(); - final var context = new PreHandleContext(accountAccess, txnWith(op)); + final var context = new FakePreHandleContext(accountStore, txnWith(op)); + context.registerStore(ReadableTopicStore.class, readableStore); - subject.preHandle(context, readableStore); + subject.preHandle(context); assertThat(context.payerKey()).isEqualTo(adminKey); // auto-renew key @@ -458,8 +463,8 @@ void autoRenewAccountKeyAdded() throws PreCheckException { @Test void missingAutoRenewAccountFails() throws PreCheckException { - given(accountAccess.getAccountById(autoRenewId)).willReturn(null); - given(accountAccess.getAccountById(payerId)).willReturn(account); + given(accountStore.getAccountById(autoRenewId)).willReturn(null); + given(accountStore.getAccountById(payerId)).willReturn(account); given(account.key()).willReturn(adminKey); final var op = OP_BUILDER @@ -467,8 +472,10 @@ void missingAutoRenewAccountFails() throws PreCheckException { .topicID(TopicID.newBuilder().topicNum(1L).build()) .build(); - final var context = new PreHandleContext(accountAccess, txnWith(op)); - assertThrowsPreCheck(() -> subject.preHandle(context, readableStore), INVALID_AUTORENEW_ACCOUNT); + final var context = new FakePreHandleContext(accountStore, txnWith(op)); + context.registerStore(ReadableTopicStore.class, readableStore); + + assertThrowsPreCheck(() -> subject.preHandle(context), INVALID_AUTORENEW_ACCOUNT); } private TransactionBody txnWith(final ConsensusUpdateTopicTransactionBody op) { diff --git a/hedera-node/hedera-consensus-service-impl/src/test/java/module-info.java b/hedera-node/hedera-consensus-service-impl/src/test/java/module-info.java index 65ab9d29607e..b647bc6d01d1 100644 --- a/hedera-node/hedera-consensus-service-impl/src/test/java/module-info.java +++ b/hedera-node/hedera-consensus-service-impl/src/test/java/module-info.java @@ -1,6 +1,7 @@ open module com.hedera.node.app.service.consensus.impl.test { requires com.hedera.node.app.service.consensus; requires com.hedera.node.app.service.consensus.impl; + requires com.hedera.node.app.service.token; requires org.junit.jupiter.api; requires com.hedera.node.app.service.mono.testFixtures; requires com.hedera.node.app.service.mono; diff --git a/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/ReadableTopicStore.java b/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/ReadableTopicStore.java new file mode 100644 index 000000000000..11f98497e84d --- /dev/null +++ b/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/ReadableTopicStore.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.node.app.service.consensus; + +import com.hedera.hapi.node.base.TopicID; +import com.hedera.hapi.node.state.consensus.Topic; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Optional; + +/** + * Provides read-only methods for interacting with the underlying data storage mechanisms for + * working with Topics. + * + *

This class is not exported from the module. It is an internal implementation detail. + */ +public interface ReadableTopicStore { + + /** + * Returns the topic metadata needed. If the topic doesn't exist returns failureReason. If the + * topic exists , the failure reason will be null. + * + * @param id topic id being looked up + * @return topic's metadata + */ + // TODO : Change to return Topic instead of TopicMetadata + @Nullable + TopicMetadata getTopicMetadata(@Nullable TopicID id); + + @NonNull + Optional getTopicLeaf(@NonNull TopicID id); +} diff --git a/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/TopicMetadata.java b/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/TopicMetadata.java new file mode 100644 index 000000000000..d21e45252ae6 --- /dev/null +++ b/hedera-node/hedera-consensus-service/src/main/java/com/hedera/node/app/service/consensus/TopicMetadata.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.node.app.service.consensus; + +import com.hedera.hapi.node.base.Key; +import com.hedera.hapi.node.base.Timestamp; +import java.util.Optional; +import java.util.OptionalLong; + +// TODO : Remove use of TopicMetadata and change to use Topic instead +/** + * Topic metadata + * + * @param memo topic's memo + * @param adminKey topic's admin key + * @param submitKey topic's submit key + * @param autoRenewDurationSeconds topic's auto-renew duration in seconds + * @param autoRenewAccountId topic's auto-renew account id + * @param expirationTimestamp topic's expiration timestamp + * @param sequenceNumber topic's sequence number + * @param runningHash topic's running hash + * @param key topic's key + * @param isDeleted topic's deleted flag + */ +public record TopicMetadata( + Optional memo, + Key adminKey, + Key submitKey, + long autoRenewDurationSeconds, + OptionalLong autoRenewAccountId, + Timestamp expirationTimestamp, + long sequenceNumber, + byte[] runningHash, + long key, + boolean isDeleted) {}