From 5003b18b657b6213ef7f26bbea525e8750846ec7 Mon Sep 17 00:00:00 2001 From: David S Bakin <117694041+david-bakin-sl@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:21:57 -0800 Subject: [PATCH] Smart contract service metrics, P2 priority. These are the metrics that are interesting now and we can collect in the consensus node, but later we'll collect in other ways. E.g., from block nodes. (All these metrics are for post-consensus transactions and will show up in the record/block stream.) Does _not_ include metrics for ExchangeRate and PNRG system contracts: Those system contracts are coded differently (don't use the same base (abstract) classes as HAS/HSS/HTS) and so will need a bit more work. Related issue(s): Fixes #16088 Reviewer notes: Changes a boatload of files. Each of the ~60 FooTranslator classes (about one for each system contract method) needs a small change, but that's a change to the construtor, and so it had effects on all the unit tests for those classes as well. You'll quickly see the pattern ... Signed-off-by: David S Bakin <117694041+david-bakin-sl@users.noreply.github.com> --- .../com/hedera/node/app/spi/RpcService.java | 10 + .../main/java/com/hedera/node/app/Hedera.java | 13 +- .../impl/ContractServiceComponent.java | 24 +- .../contract/impl/ContractServiceImpl.java | 66 +++- .../impl/exec/metrics/ContractMetrics.java | 185 ++++++--- .../CustomMessageCallProcessor.java | 4 +- .../systemcontracts/HasSystemContract.java | 8 +- .../systemcontracts/HssSystemContract.java | 8 +- .../systemcontracts/HtsSystemContract.java | 8 +- .../systemcontracts/common/AbstractCall.java | 10 + .../common/AbstractCallAttempt.java | 42 +++ .../common/AbstractCallTranslator.java | 57 ++- .../common/AbstractNativeSystemContract.java | 25 +- .../exec/systemcontracts/common/Call.java | 7 +- .../common/CallTranslator.java | 23 +- .../systemcontracts/has/HasCallAttempt.java | 10 + .../systemcontracts/has/HasCallFactory.java | 7 +- .../EvmAddressAliasTranslator.java | 27 +- .../HbarAllowanceTranslator.java | 35 +- .../hbarapprove/HbarApproveTranslator.java | 32 +- .../HederaAccountNumAliasTranslator.java | 27 +- .../isauthorized/IsAuthorizedTranslator.java | 26 +- .../IsAuthorizedRawTranslator.java | 28 +- .../isvalidalias/IsValidAliasTranslator.java | 26 +- ...etUnlimitedAutoAssociationsTranslator.java | 25 +- .../systemcontracts/hss/HssCallAttempt.java | 10 + .../systemcontracts/hss/HssCallFactory.java | 7 +- .../signschedule/SignScheduleTranslator.java | 37 +- .../systemcontracts/hts/HtsCallAttempt.java | 10 + .../systemcontracts/hts/HtsCallFactory.java | 7 +- .../hts/airdrops/TokenAirdropTranslator.java | 27 +- .../hts/allowance/GetAllowanceTranslator.java | 37 +- .../associations/AssociationsTranslator.java | 55 ++- .../hts/balanceof/BalanceOfTranslator.java | 29 +- .../hts/burn/BurnTranslator.java | 33 +- .../TokenCancelAirdropDecoder.java | 2 +- .../TokenCancelAirdropTranslator.java | 47 ++- .../TokenClaimAirdropDecoder.java | 2 +- .../TokenClaimAirdropTranslator.java | 49 ++- .../hts/create/CreateTranslator.java | 338 ++++++++++------- .../customfees/TokenCustomFeesTranslator.java | 33 +- .../hts/decimals/DecimalsTranslator.java | 28 +- .../DefaultFreezeStatusTranslator.java | 31 +- .../DefaultKycStatusTranslator.java | 31 +- .../hts/delete/DeleteTranslator.java | 26 +- .../hts/freeze/FreezeUnfreezeTranslator.java | 31 +- .../FungibleTokenInfoCall.java | 2 +- .../FungibleTokenInfoTranslator.java | 47 ++- .../getapproved/GetApprovedTranslator.java | 36 +- .../GrantApprovalTranslator.java | 47 ++- .../GrantRevokeKycTranslator.java | 31 +- .../IsApprovedForAllTranslator.java | 33 +- .../isassociated/IsAssociatedTranslator.java | 25 +- .../hts/isfrozen/IsFrozenTranslator.java | 30 +- .../hts/iskyc/IsKycTranslator.java | 30 +- .../hts/istoken/IsTokenTranslator.java | 30 +- .../hts/mint/MintTranslator.java | 34 +- .../hts/name/NameTranslator.java | 28 +- .../hts/nfttokeninfo/NftTokenInfoCall.java | 2 +- .../nfttokeninfo/NftTokenInfoTranslator.java | 45 ++- .../hts/ownerof/OwnerOfTranslator.java | 28 +- .../hts/pauses/PausesTranslator.java | 32 +- .../rejecttokens/RejectTokensTranslator.java | 49 ++- .../SetApprovalForAllTranslator.java | 37 +- .../hts/symbol/SymbolTranslator.java | 28 +- .../tokenexpiry/TokenExpiryTranslator.java | 31 +- .../hts/tokeninfo/TokenInfoCall.java | 2 +- .../hts/tokeninfo/TokenInfoTranslator.java | 47 ++- .../hts/tokenkey/TokenKeyTranslator.java | 31 +- .../hts/tokentype/TokenTypeTranslator.java | 30 +- .../hts/tokenuri/TokenUriTranslator.java | 28 +- .../totalsupply/TotalSupplyTranslator.java | 26 +- .../transfer/ClassicTransfersTranslator.java | 102 +++-- .../transfer/Erc20TransfersTranslator.java | 37 +- .../Erc721TransferFromTranslator.java | 29 +- .../hts/update/UpdateExpiryTranslator.java | 33 +- .../hts/update/UpdateKeysTranslator.java | 25 +- .../update/UpdateNFTsMetadataTranslator.java | 30 +- .../hts/update/UpdateTranslator.java | 67 ++-- .../UpdateTokenCustomFeesTranslator.java | 39 +- .../hts/wipe/WipeTranslator.java | 40 +- .../impl/exec/utils/SystemContractMethod.java | 354 ++++++++++++++++++ .../utils/SystemContractMethodRegistry.java | 106 ++++++ .../AbstractContractTransactionHandler.java | 5 + .../impl/handlers/ContractCallHandler.java | 2 +- .../handlers/ContractCallLocalHandler.java | 7 +- .../impl/handlers/ContractCreateHandler.java | 2 +- .../handlers/EthereumTransactionHandler.java | 4 +- .../src/main/java/module-info.java | 1 + .../exec/metrics/ContractMetricsTest.java | 8 +- .../systemcontracts/CallAttemptHelpers.java | 223 ++++++++++- .../HasSystemContractTest.java | 6 +- .../HssSystemContractTest.java | 6 +- .../HtsSystemContractTest.java | 6 +- .../has/HasCallAttemptTest.java | 17 +- .../has/HasCallFactoryTest.java | 12 +- .../EvmAddressAliasTranslatorTest.java | 21 +- .../HbarAllowanceTranslatorTest.java | 26 +- .../HbarApproveTranslatorTest.java | 26 +- .../HederaAccountNumAliasTranslatorTest.java | 21 +- .../IsAuthorizedTranslatorTest.java | 22 +- .../IsAuthorizedRawTranslatorTest.java | 24 +- .../IsValidAliasTranslatorTest.java | 21 +- ...limitedAutoAssociationsTranslatorTest.java | 17 +- .../hss/HssCallAttemptTest.java | 11 +- .../hss/HssCallFactoryTest.java | 12 +- .../SignScheduleTranslatorTest.java | 66 ++-- .../hts/HtsCallAttemptTest.java | 50 ++- .../hts/HtsCallFactoryTest.java | 13 +- .../airdrops/TokenAirdropTranslatorTest.java | 24 +- .../allowance/GetAllowanceTranslatorTest.java | 37 +- .../hts/burn/BurnTranslatorTest.java | 37 +- .../TokenCancelAirdropDecoderTest.java | 10 +- .../TokenCancelAirdropTranslatorTest.java | 76 ++-- .../TokenClaimAirdropDecoderTest.java | 10 +- .../TokenClaimAirdropTranslatorTest.java | 85 ++--- .../hts/create/CreateTranslatorTest.java | 95 +++-- .../TokenCustomFeesTranslatorTest.java | 31 +- .../DefaultFreezeStatusTranslatorTest.java | 31 +- .../DefaultKycStatusTranslatorTest.java | 31 +- .../hts/delete/DeleteTranslatorTest.java | 31 +- .../freeze/FreezeUnfreezeTranslatorTest.java | 42 ++- .../FungibleTokenInfoCallTest.java | 26 +- .../FungibleTokenInfoTranslatorTest.java | 34 +- .../GetApprovedTranslatorTest.java | 41 +- .../GrantApprovalTranslatorTest.java | 57 ++- .../GrantRevokeKycTranslatorTest.java | 42 ++- .../IsAssociatedTranslatorTest.java | 34 +- .../hts/isfrozen/IsFrozenTranslatorTest.java | 31 +- .../hts/iskyc/IsKycTranslatorTest.java | 31 +- .../hts/istoken/IsTokenTranslatorTest.java | 31 +- .../hts/mint/MintTranslatorTest.java | 42 ++- .../nfttokeninfo/NftTokenInfoCallTest.java | 12 +- .../NftTokenInfoTranslatorTest.java | 29 +- .../hts/pauses/PausesTranslatorTest.java | 44 ++- .../RejectTokensTranslatorTest.java | 80 ++-- .../SetApprovalForAllTranslatorTest.java | 37 +- .../TokenExpiryTranslatorTest.java | 31 +- .../hts/tokeninfo/TokenInfoCallTest.java | 18 +- .../tokeninfo/TokenInfoTranslatorTest.java | 35 +- .../hts/tokenkey/TokenKeyTranslatorTest.java | 31 +- .../tokentype/TokenTypeTranslatorTest.java | 31 +- .../ClassicTransfersTranslatorTest.java | 17 +- .../update/UpdateExpiryTranslatorTest.java | 26 +- .../hts/update/UpdateKeysTranslatorTest.java | 22 +- .../UpdateNFTsMetadataTranslatorTest.java | 19 +- .../hts/update/UpdateTranslatorTest.java | 34 +- .../UpdateTokenCustomFeesTranslatorTest.java | 22 +- .../hts/wipe/WipeTranslatorTest.java | 52 ++- .../SystemContractMethodRegistryTest.java | 148 ++++++++ .../handlers/ContractCallHandlerTest.java | 8 +- .../ContractCallLocalHandlerTest.java | 12 +- .../handlers/ContractCreateHandlerTest.java | 8 +- .../EthereumTransactionHandlerTest.java | 8 +- 154 files changed, 4156 insertions(+), 1360 deletions(-) create mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethod.java create mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethodRegistry.java create mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/utils/SystemContractMethodRegistryTest.java diff --git a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/RpcService.java b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/RpcService.java index 44a6334a3e0b..28bf0cc413a7 100644 --- a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/RpcService.java +++ b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/RpcService.java @@ -33,4 +33,14 @@ public interface RpcService extends Service { */ @NonNull Set rpcDefinitions(); + + /** + * Services may have initialization to be done which can't be done in the constructor (too soon) + * but should/must be done before the system starts processing transactions. This is the hook + * for that. + * + * Called on each Service when `Hedera.onStateInitialized() is called for `InitTrigger.GENESIS`. + * Services module is still single-threaded when this happens. + */ + default void onStateInitializedForGenesis() {} } diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java index 741bfbd2f1ce..d2466f7aaa81 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java @@ -89,10 +89,12 @@ import com.hedera.node.app.services.AppContextImpl; import com.hedera.node.app.services.ServiceMigrator; import com.hedera.node.app.services.ServicesRegistry; +import com.hedera.node.app.services.ServicesRegistry.Registration; import com.hedera.node.app.signature.AppSignatureVerifier; import com.hedera.node.app.signature.impl.SignatureExpanderImpl; import com.hedera.node.app.signature.impl.SignatureVerifierImpl; import com.hedera.node.app.spi.AppContext; +import com.hedera.node.app.spi.RpcService; import com.hedera.node.app.spi.workflows.PreCheckException; import com.hedera.node.app.state.MerkleStateLifecyclesImpl; import com.hedera.node.app.state.recordcache.RecordCacheService; @@ -606,7 +608,16 @@ public void onStateInitialized( } // With the States API grounded in the working state, we can create the object graph from it initializeDagger(state, trigger); - contractServiceImpl.registerMetrics(); + + // Tell each service it can do its final initialization (if needed) before the system starts + // processing transactions. + if (trigger == GENESIS) { + servicesRegistry.registrations().stream() + .map(Registration::service) + .filter(RpcService.class::isInstance) + .map(RpcService.class::cast) + .forEach(RpcService::onStateInitializedForGenesis); + } } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceComponent.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceComponent.java index 16ebea137121..baa5757bab9d 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceComponent.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceComponent.java @@ -18,6 +18,11 @@ import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.handlers.ContractHandlers; import com.hedera.node.app.spi.signatures.SignatureVerifier; import dagger.BindsInstance; @@ -26,6 +31,8 @@ import java.time.InstantSource; import java.util.List; import java.util.function.Supplier; +import javax.inject.Named; +import javax.inject.Provider; import javax.inject.Singleton; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -52,7 +59,8 @@ ContractServiceComponent create( @BindsInstance SignatureVerifier signatureVerifier, @BindsInstance VerificationStrategies verificationStrategies, @BindsInstance @Nullable Supplier> addOnTracers, - @BindsInstance ContractMetrics contractMetrics); + @BindsInstance ContractMetrics contractMetrics, + @BindsInstance SystemContractMethodRegistry systemContractMethodRegistry); } /** @@ -64,4 +72,18 @@ ContractServiceComponent create( * @return contract metrics collection, instance */ ContractMetrics contractMetrics(); + + /** + * @return method registry for system contracts + */ + SystemContractMethodRegistry systemContractMethodRegistry(); + + @Named("HasTranslators") + Provider>> hasCallTranslators(); + + @Named("HssTranslators") + Provider>> hssCallTranslators(); + + @Named("HtsTranslators") + Provider>> htsCallTranslators(); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceImpl.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceImpl.java index 1e0b8e14e094..831193164a5f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceImpl.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceImpl.java @@ -22,6 +22,10 @@ import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.DefaultVerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.handlers.ContractHandlers; import com.hedera.node.app.service.contract.impl.schemas.V0490ContractSchema; import com.hedera.node.app.service.contract.impl.schemas.V0500ContractSchema; @@ -30,15 +34,19 @@ import com.swirlds.state.lifecycle.SchemaRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.function.Supplier; +import java.util.stream.Collectors; +import javax.inject.Singleton; import org.hyperledger.besu.evm.tracing.OperationTracer; /** * Implementation of the {@link ContractService}. */ public class ContractServiceImpl implements ContractService { + /** * Minimum gas required for contract operations. */ @@ -66,7 +74,10 @@ public ContractServiceImpl( final var metricsSupplier = requireNonNull(appContext.metricsSupplier()); final Supplier contractsConfigSupplier = () -> appContext.configSupplier().get().getConfigData(ContractsConfig.class); - final var contractMetrics = new ContractMetrics(metricsSupplier, contractsConfigSupplier); + final var systemContractMethodRegistry = new SystemContractMethodRegistry(); + final var contractMetrics = + new ContractMetrics(metricsSupplier, contractsConfigSupplier, systemContractMethodRegistry); + this.component = DaggerContractServiceComponent.factory() .create( appContext.instantSource(), @@ -75,7 +86,8 @@ public ContractServiceImpl( appContext.signatureVerifier(), Optional.ofNullable(verificationStrategies).orElseGet(DefaultVerificationStrategies::new), addOnTracers, - contractMetrics); + contractMetrics, + systemContractMethodRegistry); } @Override @@ -84,12 +96,19 @@ public void registerSchemas(@NonNull final SchemaRegistry registry) { registry.register(new V0500ContractSchema()); } - /** - * Create the metrics for the smart contracts service. This needs to be delayed until _after_ - * the metrics are available - which happens after `Hedera.initializeStatesApi`. - */ - public void registerMetrics() { - component.contractMetrics().createContractMetrics(); + @Override + public void onStateInitializedForGenesis() { + // Force call translators to be instantiated now, so that all the system contract methods + // will be registered, so the secondary metrics can be created. (Left to its own devices + // Dagger would delay instantiating them until transactions started flowing.) + final var allTranslators = allCallTranslators(); + + // TESTING + final var msg = "Known call translators:\n" + allTranslatorNames(allTranslators); + // END TESTING + + component.contractMetrics().createContractPrimaryMetrics(); + component.contractMetrics().createContractSecondaryMetrics(); } /** @@ -98,4 +117,35 @@ public void registerMetrics() { public ContractHandlers handlers() { return component.handlers(); } + + private @NonNull List>> allCallTranslators() { + final var allCallTranslators = new ArrayList>>(); + allCallTranslators.addAll(component.hasCallTranslators().get()); + allCallTranslators.addAll(component.hssCallTranslators().get()); + allCallTranslators.addAll(component.htsCallTranslators().get()); + return allCallTranslators; + } + + // ----------------- + // For testing only: + + private @NonNull String allTranslatorNames( + @NonNull List>> translators) { + return translators.stream().map(this::translatorName).sorted().collect(Collectors.joining("\n")); + } + + private @NonNull String translatorName(@NonNull final CallTranslator> translator) { + final var simpleName = translator.getClass().getSimpleName(); + final var isSingleton = isSingleton(translator.getClass()); + final var contractName = translator instanceof AbstractCallTranslator act ? act.kind() : ""; + + var name = contractName + "." + simpleName; + if (!isSingleton) name += "(NOT-SINGLETON)"; + + return name; + } + + private boolean isSingleton(Class klass) { + return klass.getDeclaredAnnotation(Singleton.class) != null; + } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/metrics/ContractMetrics.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/metrics/ContractMetrics.java index 421528bdcddc..690162366916 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/metrics/ContractMetrics.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/metrics/ContractMetrics.java @@ -24,7 +24,10 @@ import com.google.common.annotations.VisibleForTesting; import com.hedera.hapi.node.base.HederaFunctionality; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; +import com.swirlds.common.metrics.platform.prometheus.NameConverter; import com.swirlds.metrics.api.Counter; import com.swirlds.metrics.api.Metric; import com.swirlds.metrics.api.Metrics; @@ -32,12 +35,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.hyperledger.besu.evm.frame.MessageFrame; /** * Metrics collection management for Smart Contracts service @@ -52,6 +57,8 @@ public class ContractMetrics { private final Supplier metricsSupplier; private final Supplier contractsConfigSupplier; private boolean p1MetricsEnabled; + private boolean p2MetricsEnabled; + private final SystemContractMethodRegistry systemContractMethodRegistry; private final HashMap rejectedTxsCounters = new HashMap<>(); private final HashMap rejectedTxsLackingIntrinsicGas = new HashMap<>(); @@ -80,71 +87,99 @@ public class ContractMetrics { @Inject public ContractMetrics( @NonNull final Supplier metricsSupplier, - @NonNull final Supplier contractsConfigSupplier) { + @NonNull final Supplier contractsConfigSupplier, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry) { this.metricsSupplier = requireNonNull( metricsSupplier, "metrics supplier (from platform via ServicesMain/Hedera must not be null"); this.contractsConfigSupplier = requireNonNull(contractsConfigSupplier, "contracts configuration supplier must not be null"); + this.systemContractMethodRegistry = + requireNonNull(systemContractMethodRegistry, "systemContractMethodRegistry must not be null"); } - private final Object metricsCreationLock = new Object(); - private volatile boolean primaryMetricsAreCreated = false; - - public void createContractMetrics() { - - // Primary metrics are a fixed set and can be created when `Hedera` initializes the system. - // But it actually must wait until the platform calls `Hedera.onStateInitialized` and, - // remarkably, that can happen more than once. We must only create the metrics the - // _first_ time. Hence, the simple gate here. - - synchronized (metricsCreationLock) { - if (!primaryMetricsAreCreated) { - - final var contractsConfig = requireNonNull(contractsConfigSupplier.get()); - this.p1MetricsEnabled = contractsConfig.metricsSmartContractPrimaryEnabled(); - - final var metrics = requireNonNull(metricsSupplier.get()); - - if (p1MetricsEnabled) { - // Rejected transactions counters - for (final var txKind : POSSIBLE_FAILING_TX_TYPES.keySet()) { - final var name = toRejectedName(txKind, REJECTED_TXN_SHORT_DESCR); - final var descr = toRejectedDescr(txKind, REJECTED_TXN_SHORT_DESCR); - final var config = new Counter.Config(METRIC_CATEGORY, name) - .withDescription(descr) - .withUnit(METRIC_TXN_UNIT); - final var metric = newCounter(metrics, config); - rejectedTxsCounters.put(txKind, metric); - } - - // Rejected transactions because they don't even have intrinsic gas - for (final var txKind : POSSIBLE_FAILING_TX_TYPES.keySet()) { - final var functionalityName = POSSIBLE_FAILING_TX_TYPES.get(txKind) + "DueToIntrinsicGas"; - final var name = toRejectedName(functionalityName, REJECTED_FOR_GAS_SHORT_DESCR); - final var descr = toRejectedDescr(functionalityName, REJECTED_FOR_GAS_SHORT_DESCR); - final var config = new Counter.Config(METRIC_CATEGORY, name) - .withDescription(descr) - .withUnit(METRIC_TXN_UNIT); - final var metric = newCounter(metrics, config); - rejectedTxsLackingIntrinsicGas.put(txKind, metric); - } - - // Rejected transactions for ethereum calls that are in type 3 blob transaction format - { - final var name = toRejectedName(REJECTED_TYPE3_FUNCTIONALITY, REJECTED_TYPE3_SHORT_DESCR); - final var descr = toRejectedDescr(REJECTED_TYPE3_FUNCTIONALITY, REJECTED_TYPE3_SHORT_DESCR); - final var config = new Counter.Config(METRIC_CATEGORY, name) - .withDescription(descr) - .withUnit(METRIC_TXN_UNIT); - final var metric = newCounter(metrics, config); - rejectedEthType3Counter = metric; - } - } - primaryMetricsAreCreated = true; + // -------------------- + // Creating the metrics + + /** + * Primary metrics are a fixed set and can be created when `Hedera` initializes the system. But + * it actually must wait until the platform calls `Hedera.onStateInitialized`, and then for + * GENESIS only. + */ + public void createContractPrimaryMetrics() { + final var contractsConfig = requireNonNull(contractsConfigSupplier.get()); + this.p1MetricsEnabled = contractsConfig.metricsSmartContractPrimaryEnabled(); + + if (p1MetricsEnabled) { + final var metrics = requireNonNull(metricsSupplier.get()); + + // Rejected transactions counters + for (final var txKind : POSSIBLE_FAILING_TX_TYPES.keySet()) { + final var name = toRejectedName(txKind, REJECTED_TXN_SHORT_DESCR); + final var descr = toRejectedDescr(txKind, REJECTED_TXN_SHORT_DESCR); + final var config = new Counter.Config(METRIC_CATEGORY, name) + .withDescription(descr) + .withUnit(METRIC_TXN_UNIT); + final var metric = newCounter(metrics, config); + rejectedTxsCounters.put(txKind, metric); + } + + // Rejected transactions because they don't even have intrinsic gas + for (final var txKind : POSSIBLE_FAILING_TX_TYPES.keySet()) { + final var functionalityName = POSSIBLE_FAILING_TX_TYPES.get(txKind) + "DueToIntrinsicGas"; + final var name = toRejectedName(functionalityName, REJECTED_FOR_GAS_SHORT_DESCR); + final var descr = toRejectedDescr(functionalityName, REJECTED_FOR_GAS_SHORT_DESCR); + final var config = new Counter.Config(METRIC_CATEGORY, name) + .withDescription(descr) + .withUnit(METRIC_TXN_UNIT); + final var metric = newCounter(metrics, config); + rejectedTxsLackingIntrinsicGas.put(txKind, metric); + } + + // Rejected transactions for ethereum calls that are in type 3 blob transaction format + { + final var name = toRejectedName(REJECTED_TYPE3_FUNCTIONALITY, REJECTED_TYPE3_SHORT_DESCR); + final var descr = toRejectedDescr(REJECTED_TYPE3_FUNCTIONALITY, REJECTED_TYPE3_SHORT_DESCR); + final var config = new Counter.Config(METRIC_CATEGORY, name) + .withDescription(descr) + .withUnit(METRIC_TXN_UNIT); + final var metric = newCounter(metrics, config); + rejectedEthType3Counter = metric; } } } + public void createContractSecondaryMetrics() { + + if (systemContractMethodRegistry.size() == 0) { + // Something went wrong with the order in which components were initialized + log.warn("no system contract methods registered when trying to create secondary metrics"); + } + + // TESTING + final var msg1 = systemContractMethodRegistry.allQualifiedMethods().stream() + .sorted() + .collect(Collectors.joining("\n")); + + final var msg2 = + systemContractMethodRegistry + .allMethodsGivenMapper(SystemContractMethod::fullyDecoratedMethodName) + .stream() + .sorted() + .collect(Collectors.joining("\n")); + // END TESTING + + final var contractsConfig = requireNonNull(contractsConfigSupplier.get()); + this.p2MetricsEnabled = contractsConfig.metricsSmartContractSecondaryEnabled(); + + if (p2MetricsEnabled) { + final var metrics = requireNonNull(metricsSupplier.get()); + // TBD + } + } + + // --------------------------------- + // P1 metrics: `pureCheck` failures + public void incrementRejectedTx(@NonNull final HederaFunctionality txKind) { bumpRejectedTx(txKind, 1); } @@ -174,6 +209,31 @@ public void bumpRejectedType3EthTx(final long bumpBy) { } } + // --------------------------------------------- + // P2 metrics: System contract per-method counts + + public void incrementSystemMethodCall( + @NonNull final SystemContractMethod systemContractMethod, @NonNull final MessageFrame.State state) { + // Response code says whether succeed/failure or other + } + + private final ConcurrentHashMap methodsThatHaveCallsWithNullMethod = + new ConcurrentHashMap<>(50); + + public void logWarnMissingSystemContractMethodOnCall(@NonNull final SystemContractMethod systemContractMethod) { + // Log, but only first time you see it for a specific method (to avoid spew) + requireNonNull(systemContractMethod); + if (methodsThatHaveCallsWithNullMethod.containsKey(systemContractMethod)) { + log.warn("Found `Call` without `SystemContractMethod`, %s" + .formatted(systemContractMethod.fullyDecoratedMethodName())); + } else { + methodsThatHaveCallsWithNullMethod.put(systemContractMethod, systemContractMethod); + } + } + + // ----------------- + // Unit test helpers + @VisibleForTesting public @NonNull Map getAllCounters() { return Stream.concat( @@ -216,6 +276,9 @@ public void bumpRejectedType3EthTx(final long bumpBy) { .collect(Collectors.joining(", ", "{", "}")); } + // --------------------------------- + // Helpers for making metrics' names + private @NonNull Counter newCounter(@NonNull final Metrics metrics, @NonNull final Counter.Config config) { return metrics.getOrCreate(config); } @@ -244,6 +307,16 @@ public void bumpRejectedType3EthTx(final long bumpBy) { @NonNull final String template, @NonNull final String functionality, @NonNull final String shortDescription) { - return template.formatted(functionality, METRIC_SERVICE, shortDescription); + final var possiblyUnacceptableName = template.formatted(functionality, METRIC_SERVICE, shortDescription); + final var definitelyAcceptableName = NameConverter.fix(possiblyUnacceptableName); + + // TESTING + if (!definitelyAcceptableName.equals(possiblyUnacceptableName)) { + // Just want to signal this during testing: i.e., to be able to place a breakpoint here + ; + } + // END TESTING + + return definitelyAcceptableName; } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java index dc342952650c..5259ddc517de 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java @@ -21,7 +21,7 @@ import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INSUFFICIENT_CHILD_RECORDS; import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_CONTRACT_ID; import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_SIGNATURE; -import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.create.CreateTranslator.createSelectorsMap; +import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.create.CreateTranslator.createMethodsMap; import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.acquiredSenderAuthorizationViaDelegateCall; import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.alreadyHalted; import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.isTopLevelTransaction; @@ -195,7 +195,7 @@ private boolean isTokenCreation(MessageFrame frame) { return false; } var selector = frame.getInputData().slice(0, 4).toArray(); - return createSelectorsMap.keySet().stream().anyMatch(s -> Arrays.equals(s.selector(), selector)); + return createMethodsMap.keySet().stream().anyMatch(s -> Arrays.equals(s.selector(), selector)); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HasSystemContract.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HasSystemContract.java index 767e7240ae30..42fefdd745fb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HasSystemContract.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HasSystemContract.java @@ -23,6 +23,7 @@ import static java.util.Objects.requireNonNull; import com.hedera.hapi.node.base.ContractID; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractNativeSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallFactory; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; @@ -42,8 +43,11 @@ public class HasSystemContract extends AbstractNativeSystemContract implements H public static final ContractID HAS_CONTRACT_ID = asNumberedContractId(Address.fromHexString(HAS_EVM_ADDRESS)); @Inject - public HasSystemContract(@NonNull final GasCalculator gasCalculator, @NonNull final HasCallFactory callFactory) { - super(HAS_SYSTEM_CONTRACT_NAME, callFactory, HAS_CONTRACT_ID, gasCalculator); + public HasSystemContract( + @NonNull final GasCalculator gasCalculator, + @NonNull final HasCallFactory callFactory, + @NonNull final ContractMetrics contractMetrics) { + super(HAS_SYSTEM_CONTRACT_NAME, callFactory, HAS_CONTRACT_ID, gasCalculator, contractMetrics); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HssSystemContract.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HssSystemContract.java index beb29fd7d3be..85a8325a8a10 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HssSystemContract.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HssSystemContract.java @@ -23,6 +23,7 @@ import static java.util.Objects.requireNonNull; import com.hedera.hapi.node.base.ContractID; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractNativeSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallFactory; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; @@ -45,8 +46,11 @@ public class HssSystemContract extends AbstractNativeSystemContract implements H public static final ContractID HSS_CONTRACT_ID = asNumberedContractId(Address.fromHexString(HSS_EVM_ADDRESS)); @Inject - public HssSystemContract(@NonNull final GasCalculator gasCalculator, @NonNull final HssCallFactory callFactory) { - super(HSS_SYSTEM_CONTRACT_NAME, callFactory, HSS_CONTRACT_ID, gasCalculator); + public HssSystemContract( + @NonNull final GasCalculator gasCalculator, + @NonNull final HssCallFactory callFactory, + @NonNull final ContractMetrics contractMetrics) { + super(HSS_SYSTEM_CONTRACT_NAME, callFactory, HSS_CONTRACT_ID, gasCalculator, contractMetrics); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HtsSystemContract.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HtsSystemContract.java index 1fd08a99a7f2..f57f0b9b9683 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HtsSystemContract.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/HtsSystemContract.java @@ -19,6 +19,7 @@ import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asNumberedContractId; import com.hedera.hapi.node.base.ContractID; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractNativeSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallFactory; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; @@ -37,8 +38,11 @@ public class HtsSystemContract extends AbstractNativeSystemContract implements H public static final ContractID HTS_CONTRACT_ID = asNumberedContractId(Address.fromHexString(HTS_EVM_ADDRESS)); @Inject - public HtsSystemContract(@NonNull final GasCalculator gasCalculator, @NonNull final HtsCallFactory callFactory) { - super(HTS_SYSTEM_CONTRACT_NAME, callFactory, HTS_CONTRACT_ID, gasCalculator); + public HtsSystemContract( + @NonNull final GasCalculator gasCalculator, + @NonNull final HtsCallFactory callFactory, + @NonNull final ContractMetrics contractMetrics) { + super(HTS_SYSTEM_CONTRACT_NAME, callFactory, HTS_CONTRACT_ID, gasCalculator, contractMetrics); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCall.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCall.java index 6d7cda70e042..17bdf0d56005 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCall.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCall.java @@ -29,6 +29,7 @@ import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.HederaOperations; import com.hedera.node.app.service.contract.impl.exec.scope.SystemContractOperations; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.records.ContractCallStreamBuilder; import com.hedera.node.app.service.token.ReadableAccountStore; @@ -43,6 +44,7 @@ public abstract class AbstractCall implements Call { protected final SystemContractGasCalculator gasCalculator; protected final HederaWorldUpdater.Enhancement enhancement; private final boolean isViewCall; + private SystemContractMethod systemContractMethod; protected AbstractCall( @NonNull final SystemContractGasCalculator gasCalculator, @@ -53,6 +55,14 @@ protected AbstractCall( this.isViewCall = isViewCall; } + public void setSystemContractMethod(@NonNull final SystemContractMethod systemContractMethod) { + this.systemContractMethod = systemContractMethod; + } + + public SystemContractMethod getSystemContractMethod() { + return systemContractMethod; + } + protected HederaOperations operations() { return enhancement.operations(); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallAttempt.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallAttempt.java index c05adca731c0..2b475530449c 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallAttempt.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallAttempt.java @@ -26,6 +26,9 @@ import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.swirlds.config.api.Configuration; import edu.umd.cs.findbugs.annotations.NonNull; @@ -33,6 +36,7 @@ import java.nio.BufferUnderflowException; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; @@ -54,6 +58,7 @@ public abstract class AbstractCallAttempt> { private final VerificationStrategies verificationStrategies; private final SystemContractGasCalculator gasCalculator; private final List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry; private final boolean isStaticCall; // If non-null, the address of a non-contract entity (e.g., account or token) whose @@ -89,6 +94,7 @@ public AbstractCallAttempt( @NonNull final SystemContractGasCalculator gasCalculator, @NonNull final List> callTranslators, final boolean isStaticCall, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, @NonNull final com.esaulpaugh.headlong.abi.Function redirectFunction) { requireNonNull(input); requireNonNull(redirectFunction); @@ -101,6 +107,7 @@ public AbstractCallAttempt( this.enhancement = requireNonNull(enhancement); this.verificationStrategies = requireNonNull(verificationStrategies); this.onlyDelegatableContractKeysActive = onlyDelegatableContractKeysActive; + this.systemContractMethodRegistry = requireNonNull(systemContractMethodRegistry); if (isRedirectSelector(redirectFunction.selector(), input.toArrayUnsafe())) { Tuple abiCall = null; @@ -127,6 +134,8 @@ public AbstractCallAttempt( this.isStaticCall = isStaticCall; } + protected abstract SystemContract systemContractKind(); + protected abstract T self(); /** @@ -277,6 +286,24 @@ public boolean isSelector(@NonNull final Function... functions) { return false; } + /** + * Returns whether this call attempt is a selector for any of the given functions. + * @param methods selectors to match against + * @return boolean result + */ + public boolean isSelector(@NonNull final SystemContractMethod... methods) { + return isMethod(methods).isPresent(); + } + + public @NonNull Optional isMethod(@NonNull final SystemContractMethod... methods) { + for (final var method : methods) { + if (Arrays.equals(method.selector(), this.selector())) { + return Optional.of(method); + } + } + return Optional.empty(); + } + /** * Returns whether this call attempt is a selector for any of the given functions. * @param configEnabled whether the config is enabled @@ -287,6 +314,17 @@ public boolean isSelectorIfConfigEnabled(final boolean configEnabled, @NonNull f return configEnabled && isSelector(functions); } + /** + * Returns whether this call attempt is a selector for any of the given functions. + * @param configEnabled whether the config is enabled + * @param methods selectors to match against + * @return boolean result + */ + public boolean isSelectorIfConfigEnabled( + final boolean configEnabled, @NonNull final SystemContractMethod... methods) { + return configEnabled && isSelector(methods); + } + /** * Returns whether this call attempt is a selector for any of the given functions. * @param functionSelector bytes of the function selector @@ -305,4 +343,8 @@ private boolean isRedirectSelector(@NonNull final byte[] functionSelector, @NonN public boolean isOnlyDelegatableContractKeysActive() { return onlyDelegatableContractKeysActive; } + + public SystemContractMethodRegistry getSystemContractMethodRegistry() { + return systemContractMethodRegistry; + } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallTranslator.java index e2bc2c7904ad..b2d767e76f9a 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractCallTranslator.java @@ -18,8 +18,15 @@ import static java.util.Objects.requireNonNull; +import com.google.common.annotations.VisibleForTesting; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** * Basic implementation support for a {@link CallTranslator} that returns a translated @@ -27,15 +34,59 @@ * @param the type of the abstract call translator */ public abstract class AbstractCallTranslator> implements CallTranslator { + + private static final Logger log = LogManager.getLogger(AbstractCallTranslator.class); + + private final SystemContract systemContractKind; + private final SystemContractMethodRegistry systemContractMethodRegistry; + private final ContractMetrics contractMetrics; + + public AbstractCallTranslator( + @NonNull final SystemContract systemContractKind, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + this.systemContractKind = requireNonNull(systemContractKind); + this.systemContractMethodRegistry = requireNonNull(systemContractMethodRegistry); + this.contractMetrics = requireNonNull(contractMetrics); + } + /** * {@inheritDoc} */ @Override public @Nullable Call translateCallAttempt(@NonNull final T attempt) { requireNonNull(attempt); - if (matches(attempt)) { - return callFrom(attempt); + final var call = identifyMethod(attempt) + .map(systemContractMethod -> callFrom(attempt, systemContractMethod)) + .orElse(null); + if (call != null) { + if (call.getSystemContractMethod() == null) { + contractMetrics.logWarnMissingSystemContractMethodOnCall( + identifyMethod(attempt).orElseThrow()); + } + } + return call; + } + + public void registerMethods(@NonNull final SystemContractMethod... methods) { + requireNonNull(methods); + for (@NonNull final var method : methods) { + requireNonNull(method); + registerMethod(method.withContract(systemContractKind)); } - return null; + } + + private void registerMethod(@NonNull final SystemContractMethod method) { + requireNonNull(method); + method.verifyComplete(); + + if (systemContractMethodRegistry != null) { + systemContractMethodRegistry.register(method); + } + } + + @VisibleForTesting + public @NonNull String kind() { + return systemContractKind != null ? systemContractKind.name() : ""; } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractNativeSystemContract.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractNativeSystemContract.java index e69218d53ae4..26f2150d8af7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractNativeSystemContract.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/AbstractNativeSystemContract.java @@ -35,6 +35,7 @@ import com.hedera.hapi.node.base.ContractID; import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.AbstractFullContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.HederaSystemContract; @@ -64,15 +65,18 @@ public abstract class AbstractNativeSystemContract extends AbstractFullContract private final CallFactory callFactory; private final ContractID contractID; + private final ContractMetrics contractMetrics; protected AbstractNativeSystemContract( @NonNull String name, @NonNull CallFactory callFactory, @NonNull ContractID contractID, - @NonNull GasCalculator gasCalculator) { + @NonNull GasCalculator gasCalculator, + @NonNull ContractMetrics contractMetrics) { super(name, gasCalculator); this.callFactory = requireNonNull(callFactory); this.contractID = requireNonNull(contractID); + this.contractMetrics = requireNonNull(contractMetrics); } @Override @@ -103,7 +107,7 @@ public FullResult computeFully(@NonNull final Bytes input, @NonNull final Messag } @SuppressWarnings({"java:S2637", "java:S2259"}) // this function is going to be refactored soon. - private static FullResult resultOfExecuting( + private FullResult resultOfExecuting( @NonNull final AbstractCallAttempt attempt, @NonNull final Call call, @NonNull final Bytes input, @@ -156,12 +160,23 @@ private static FullResult resultOfExecuting( } } } catch (final HandleException handleException) { - return haltHandleException(handleException, frame.getRemainingGas()); + final var fullResult = haltHandleException(handleException, frame.getRemainingGas()); + reportToMetrics(call, fullResult); + return fullResult; } catch (final Exception internal) { log.error("Unhandled failure for input {} to native system contract", input, internal); - return haltResult(PRECOMPILE_ERROR, frame.getRemainingGas()); + final var fullResult = haltResult(PRECOMPILE_ERROR, frame.getRemainingGas()); + reportToMetrics(call, fullResult); + return fullResult; } - return pricedResult.fullResult(); + final var fullResult = pricedResult.fullResult(); + reportToMetrics(call, fullResult); + return fullResult; + } + + private void reportToMetrics(@NonNull final Call call, @NonNull final FullResult fullResult) { + contractMetrics.incrementSystemMethodCall( + call.getSystemContractMethod(), fullResult.result().getState()); } private static void externalizeFailure( diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/Call.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/Call.java index 0c0ca2286f3f..4a3d9e4d94bc 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/Call.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/Call.java @@ -25,6 +25,7 @@ import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.hapi.node.contract.ContractFunctionResult; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.FullResult; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; import com.hedera.node.app.service.contract.impl.records.ContractCallStreamBuilder; import com.hedera.pbj.runtime.io.buffer.Bytes; import edu.umd.cs.findbugs.annotations.NonNull; @@ -36,7 +37,7 @@ */ public interface Call { /** - * Encapsulates the result of a call to the HTS system contract. There are two elements, + * Encapsulates the result of a call to the HAS/HSS/HTS system contract. There are two elements, *
    *
  1. The "full result" of the call, including both its EVM-standard {@link PrecompileContractResult} * and gas requirement (which is often difficult to compute without executing the call); as well as @@ -150,4 +151,8 @@ default PricedResult execute(MessageFrame frame) { default boolean allowsStaticFrame() { return false; } + + void setSystemContractMethod(@NonNull final SystemContractMethod systemContractMethod); + + SystemContractMethod getSystemContractMethod(); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/CallTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/CallTranslator.java index f6074a40746b..db3034a02423 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/CallTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/common/CallTranslator.java @@ -17,8 +17,10 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.common; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Optional; /** * Strategy interface for translating {@link HtsCallAttempt}s into {@link Call}s. @@ -36,12 +38,11 @@ public interface CallTranslator { Call translateCallAttempt(@NonNull T attempt); /** - * Returns true if the attempt matches the selector of the call this translator is responsible for. - * - * @param attempt the selector to match - * @return true if the selector matches the selector of the call this translator is responsible for + * Returns the SystemContractMethod for this attempt's selector, if the selector is known. + * @param attempt the selector to match (in the Attempt) + * @return the SystemContractMethod for the attempt (or it can be empty if unknown) */ - boolean matches(@NonNull T attempt); + abstract @NonNull Optional identifyMethod(@NonNull final T attempt); /** * Returns a call from the given attempt. @@ -50,4 +51,16 @@ public interface CallTranslator { * @return a call from the given attempt */ Call callFrom(@NonNull T attempt); + + /** Returns a call from the given attempt + * + * @param attempt the attempt to get the call from + * @param systemContractMethod system contract method the attempt is calling + * @return a call from the given attempt hascall + */ + default Call callFrom(@NonNull final T attempt, @NonNull final SystemContractMethod systemContractMethod) { + final var call = callFrom(attempt); + call.setSystemContractMethod(systemContractMethod); + return call; + } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallAttempt.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallAttempt.java index a6cf40fedd88..e2e19e9cc7ff 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallAttempt.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallAttempt.java @@ -31,6 +31,9 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import com.swirlds.config.api.Configuration; @@ -68,6 +71,7 @@ public HasCallAttempt( @NonNull final SignatureVerifier signatureVerifier, @NonNull final SystemContractGasCalculator gasCalculator, @NonNull final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, final boolean isStaticCall) { super( input, @@ -81,6 +85,7 @@ public HasCallAttempt( gasCalculator, callTranslators, isStaticCall, + systemContractMethodRegistry, REDIRECT_FOR_ACCOUNT); if (isRedirect()) { this.redirectAccount = linkedAccount(requireNonNull(redirectAddress)); @@ -90,6 +95,11 @@ public HasCallAttempt( this.signatureVerifier = requireNonNull(signatureVerifier); } + @Override + protected SystemContract systemContractKind() { + return SystemContractMethod.SystemContract.HAS; + } + @Override protected HasCallAttempt self() { return this; diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallFactory.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallFactory.java index 16b7a2360b4f..39c1e74afefd 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallFactory.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/HasCallFactory.java @@ -27,6 +27,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.SyntheticIds; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.spi.signatures.SignatureVerifier; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; @@ -46,6 +47,7 @@ public class HasCallFactory implements CallFactory { private final VerificationStrategies verificationStrategies; private final SignatureVerifier signatureVerifier; private final List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry; @Inject public HasCallFactory( @@ -53,12 +55,14 @@ public HasCallFactory( @NonNull final CallAddressChecks addressChecks, @NonNull final VerificationStrategies verificationStrategies, @NonNull final SignatureVerifier signatureVerifier, - @NonNull @Named("HasTranslators") final List> callTranslators) { + @NonNull @Named("HasTranslators") final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry) { this.syntheticIds = requireNonNull(syntheticIds); this.addressChecks = requireNonNull(addressChecks); this.verificationStrategies = requireNonNull(verificationStrategies); this.signatureVerifier = requireNonNull(signatureVerifier); this.callTranslators = requireNonNull(callTranslators); + this.systemContractMethodRegistry = requireNonNull(systemContractMethodRegistry); } /** @@ -88,6 +92,7 @@ public HasCallFactory( signatureVerifier, systemContractGasCalculatorOf(frame), callTranslators, + systemContractMethodRegistry, frame.isStatic()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/getevmaddressalias/EvmAddressAliasTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/getevmaddressalias/EvmAddressAliasTranslator.java index 85b056884397..bc9096050eee 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/getevmaddressalias/EvmAddressAliasTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/getevmaddressalias/EvmAddressAliasTranslator.java @@ -19,11 +19,16 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,12 +38,19 @@ @Singleton public class EvmAddressAliasTranslator extends AbstractCallTranslator { /** Selector for getEvmAddressAlias(address) method. */ - public static final Function EVM_ADDRESS_ALIAS = - new Function("getEvmAddressAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS); + public static final SystemContractMethod EVM_ADDRESS_ALIAS = SystemContractMethod.declare( + "getEvmAddressAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS) + .withModifier(Modifier.VIEW) + .withCategories(Category.ALIASES); @Inject - public EvmAddressAliasTranslator() { + public EvmAddressAliasTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(EVM_ADDRESS_ALIAS); } /** @@ -52,12 +64,9 @@ public EvmAddressAliasTranslator() { return new EvmAddressAliasCall(attempt, address); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt, "attempt"); - return attempt.isSelector(EVM_ADDRESS_ALIAS); + return attempt.isMethod(EVM_ADDRESS_ALIAS); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarallowance/HbarAllowanceTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarallowance/HbarAllowanceTranslator.java index 3a687a45ae58..8d02f6a1dc27 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarallowance/HbarAllowanceTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarallowance/HbarAllowanceTranslator.java @@ -18,12 +18,18 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -34,25 +40,32 @@ public class HbarAllowanceTranslator extends AbstractCallTranslator { /** Selector for hbarAllowance(address) method. */ - public static final Function HBAR_ALLOWANCE_PROXY = - new Function("hbarAllowance(address)", ReturnTypes.RESPONSE_CODE_INT256); + public static final SystemContractMethod HBAR_ALLOWANCE_PROXY = SystemContractMethod.declare( + "hbarAllowance(address)", ReturnTypes.RESPONSE_CODE_INT256) + .withVia(CallVia.PROXY) + .withModifier(Modifier.VIEW) + .withCategories(Category.ALLOWANCE); /** Selector for hbarAllowance(address,address) method. */ - public static final Function HBAR_ALLOWANCE = - new Function("hbarAllowance(address,address)", ReturnTypes.RESPONSE_CODE_INT256); + public static final SystemContractMethod HBAR_ALLOWANCE = SystemContractMethod.declare( + "hbarAllowance(address,address)", ReturnTypes.RESPONSE_CODE_INT256) + .withModifier(Modifier.VIEW) + .withCategories(Category.ALLOWANCE); @Inject - public HbarAllowanceTranslator() { + public HbarAllowanceTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(HBAR_ALLOWANCE, HBAR_ALLOWANCE_PROXY); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt); - return attempt.isSelector(HBAR_ALLOWANCE, HBAR_ALLOWANCE_PROXY); + return attempt.isMethod(HBAR_ALLOWANCE, HBAR_ALLOWANCE_PROXY); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarapprove/HbarApproveTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarapprove/HbarApproveTranslator.java index d02d21909d61..c17475cbf9d0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarapprove/HbarApproveTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hbarapprove/HbarApproveTranslator.java @@ -18,17 +18,22 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.token.CryptoAllowance; import com.hedera.hapi.node.token.CryptoApproveAllowanceTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import java.math.BigInteger; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -39,28 +44,35 @@ public class HbarApproveTranslator extends AbstractCallTranslator { /** Selector for hbarApprove(address,int256) method. */ - public static final Function HBAR_APPROVE_PROXY = new Function("hbarApprove(address,int256)", ReturnTypes.INT_64); + public static final SystemContractMethod HBAR_APPROVE_PROXY = SystemContractMethod.declare( + "hbarApprove(address,int256)", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withCategories(Category.APPROVAL); /** Selector for hbarApprove(address,address,int256) method. */ - public static final Function HBAR_APPROVE = new Function("hbarApprove(address,address,int256)", ReturnTypes.INT_64); + public static final SystemContractMethod HBAR_APPROVE = SystemContractMethod.declare( + "hbarApprove(address,address,int256)", ReturnTypes.INT_64) + .withCategories(Category.APPROVAL); /** * Default constructor for injection. */ @Inject - public HbarApproveTranslator() { + public HbarApproveTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(HBAR_APPROVE, HBAR_APPROVE_PROXY); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt); - return attempt.isSelector(HBAR_APPROVE, HBAR_APPROVE_PROXY); - } + return attempt.isMethod(HBAR_APPROVE, HBAR_APPROVE_PROXY); + } /** * {@inheritDoc} */ diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslator.java index 430a2ef8b7a7..3332f5ff9a11 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslator.java @@ -19,25 +19,39 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class HederaAccountNumAliasTranslator extends AbstractCallTranslator { /** Selector for getHederaAccountNumAlias(address) method. */ - public static final Function HEDERA_ACCOUNT_NUM_ALIAS = - new Function("getHederaAccountNumAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS); + public static final SystemContractMethod HEDERA_ACCOUNT_NUM_ALIAS = SystemContractMethod.declare( + "getHederaAccountNumAlias(address)", ReturnTypes.RESPONSE_CODE_ADDRESS) + .withModifier(Modifier.VIEW) + .withCategories(Category.ALIASES); /** * Default constructor for injection. */ @Inject - public HederaAccountNumAliasTranslator() { + public HederaAccountNumAliasTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(HEDERA_ACCOUNT_NUM_ALIAS); } /** @@ -52,8 +66,9 @@ public HederaAccountNumAliasTranslator() { } @Override - public boolean matches(@NonNull HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt, "attempt"); - return attempt.isSelector(HEDERA_ACCOUNT_NUM_ALIAS); + + return attempt.isMethod(HEDERA_ACCOUNT_NUM_ALIAS); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslator.java index eb18982fc789..d271ae1c9873 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslator.java @@ -19,24 +19,29 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.node.app.service.contract.impl.annotations.ServicesV051; import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @Singleton public class IsAuthorizedTranslator extends AbstractCallTranslator { - public static final Function IS_AUTHORIZED = - new Function("isAuthorized(address,bytes,bytes)", ReturnTypes.RESPONSE_CODE64_BOOL); + public static final SystemContractMethod IS_AUTHORIZED = SystemContractMethod.declare( + "isAuthorized(address,bytes,bytes)", ReturnTypes.RESPONSE_CODE64_BOOL) + .withCategories(Category.IS_AUTHORIZED); private static final int ADDRESS_ARG = 0; private static final int MESSAGE_ARG = 1; private static final int SIGNATURE_BLOB_ARG = 2; @@ -46,19 +51,26 @@ public class IsAuthorizedTranslator extends AbstractCallTranslator identifyMethod(@NonNull HasCallAttempt attempt) { requireNonNull(attempt, "attempt"); - final boolean callEnabled = attempt.configuration() + final var callEnabled = attempt.configuration() .getConfigData(ContractsConfig.class) .systemContractAccountServiceIsAuthorizedEnabled(); - return callEnabled && attempt.isSelector(IS_AUTHORIZED); + + if (attempt.isSelectorIfConfigEnabled(callEnabled, IS_AUTHORIZED)) return Optional.of(IS_AUTHORIZED); + return Optional.empty(); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslator.java index 609e54c01592..69181ff5db23 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslator.java @@ -19,16 +19,20 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.node.app.service.contract.impl.annotations.ServicesV051; import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -39,8 +43,9 @@ public class IsAuthorizedRawTranslator extends AbstractCallTranslator { /** Selector for isAuthorizedRaw(address,bytes,bytes) method. */ - public static final Function IS_AUTHORIZED_RAW = - new Function("isAuthorizedRaw(address,bytes,bytes)", ReturnTypes.BOOL); + public static final SystemContractMethod IS_AUTHORIZED_RAW = SystemContractMethod.declare( + "isAuthorizedRaw(address,bytes,bytes)", ReturnTypes.BOOL) + .withCategories(Category.IS_AUTHORIZED); private static final int ADDRESS_ARG = 0; private static final int HASH_ARG = 1; @@ -51,22 +56,25 @@ public class IsAuthorizedRawTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt, "attempt"); - final boolean callEnabled = attempt.configuration() + final var callEnabled = attempt.configuration() .getConfigData(ContractsConfig.class) .systemContractAccountServiceIsAuthorizedRawEnabled(); - return callEnabled && attempt.isSelector(IS_AUTHORIZED_RAW); + if (attempt.isSelectorIfConfigEnabled(callEnabled, IS_AUTHORIZED_RAW)) return Optional.of(IS_AUTHORIZED_RAW); + return Optional.empty(); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslator.java index 45f425931336..570e339355fb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslator.java @@ -19,25 +19,40 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class IsValidAliasTranslator extends AbstractCallTranslator { /** Selector for isValidAlias(address) method. */ - public static final Function IS_VALID_ALIAS = new Function("isValidAlias(address)", ReturnTypes.BOOL); + public static final SystemContractMethod IS_VALID_ALIAS = SystemContractMethod.declare( + "isValidAlias(address)", ReturnTypes.BOOL) + .withModifier(Modifier.VIEW) + .withCategories(Category.ALIASES); /** * Default constructor for injection. */ @Inject - public IsValidAliasTranslator() { + public IsValidAliasTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(IS_VALID_ALIAS); } @Override @@ -48,8 +63,9 @@ public IsValidAliasTranslator() { } @Override - public boolean matches(@NonNull HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { requireNonNull(attempt, "attempt"); - return attempt.isSelector(IS_VALID_ALIAS); + + return attempt.isMethod(IS_VALID_ALIAS); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslator.java index 4c289164d8b0..967f73b3c436 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslator.java @@ -18,38 +18,51 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.token.CryptoUpdateTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @Singleton public class SetUnlimitedAutoAssociationsTranslator extends AbstractCallTranslator { - public static final Function SET_UNLIMITED_AUTO_ASSOC = - new Function("setUnlimitedAutomaticAssociations(bool)", ReturnTypes.INT_64); + public static final SystemContractMethod SET_UNLIMITED_AUTO_ASSOC = SystemContractMethod.declare( + "setUnlimitedAutomaticAssociations(bool)", ReturnTypes.INT_64) + .withCategories(Category.ASSOCIATION); private static final int UNLIMITED_AUTO_ASSOCIATIONS = -1; private static final int NO_AUTO_ASSOCIATIONS = 0; @Inject - public SetUnlimitedAutoAssociationsTranslator() { + public SetUnlimitedAutoAssociationsTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HAS, systemContractMethodRegistry, contractMetrics); + + registerMethods(SET_UNLIMITED_AUTO_ASSOC); } @Override - public boolean matches(@NonNull final HasCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HasCallAttempt attempt) { final var setUnlimitedAutoAssocEnabled = attempt.configuration() .getConfigData(ContractsConfig.class) .systemContractSetUnlimitedAutoAssociationsEnabled(); - return attempt.isSelectorIfConfigEnabled(setUnlimitedAutoAssocEnabled, SET_UNLIMITED_AUTO_ASSOC); + + if (attempt.isSelectorIfConfigEnabled(setUnlimitedAutoAssocEnabled, SET_UNLIMITED_AUTO_ASSOC)) + return Optional.of(SET_UNLIMITED_AUTO_ASSOC); + return Optional.empty(); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallAttempt.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallAttempt.java index 7f9f87a3e949..e01c1811c0ad 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallAttempt.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallAttempt.java @@ -31,6 +31,9 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.swirlds.config.api.Configuration; import edu.umd.cs.findbugs.annotations.NonNull; @@ -63,6 +66,7 @@ public HssCallAttempt( @NonNull final VerificationStrategies verificationStrategies, @NonNull final SystemContractGasCalculator gasCalculator, @NonNull final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, final boolean isStaticCall) { super( input, @@ -76,6 +80,7 @@ public HssCallAttempt( gasCalculator, callTranslators, isStaticCall, + systemContractMethodRegistry, REDIRECT_FOR_SCHEDULE_TXN); if (isRedirect()) { this.redirectScheduleTxn = linkedSchedule(requireNonNull(redirectAddress)); @@ -84,6 +89,11 @@ public HssCallAttempt( } } + @Override + protected SystemContract systemContractKind() { + return SystemContractMethod.SystemContract.HSS; + } + @Override protected HssCallAttempt self() { return this; diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallFactory.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallFactory.java index b503840b2730..9f1ef0c50e5f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallFactory.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/HssCallFactory.java @@ -27,6 +27,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.SyntheticIds; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.spi.signatures.SignatureVerifier; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; @@ -45,6 +46,7 @@ public class HssCallFactory implements CallFactory { private final CallAddressChecks addressChecks; private final VerificationStrategies verificationStrategies; private final List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry; @Inject public HssCallFactory( @@ -52,11 +54,13 @@ public HssCallFactory( @NonNull final CallAddressChecks addressChecks, @NonNull final VerificationStrategies verificationStrategies, @NonNull final SignatureVerifier signatureVerifier, - @NonNull @Named("HssTranslators") final List> callTranslators) { + @NonNull @Named("HssTranslators") final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry) { this.syntheticIds = requireNonNull(syntheticIds); this.addressChecks = requireNonNull(addressChecks); this.verificationStrategies = requireNonNull(verificationStrategies); this.callTranslators = requireNonNull(callTranslators); + this.systemContractMethodRegistry = requireNonNull(systemContractMethodRegistry); } /** @@ -85,6 +89,7 @@ public HssCallFactory( verificationStrategies, systemContractGasCalculatorOf(frame), callTranslators, + systemContractMethodRegistry, frame.isStatic()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/signschedule/SignScheduleTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/signschedule/SignScheduleTranslator.java index 9ff82e104920..d3c447c1a3a7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/signschedule/SignScheduleTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hss/signschedule/SignScheduleTranslator.java @@ -26,7 +26,6 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.ContractID; import com.hedera.hapi.node.base.Key; @@ -35,14 +34,20 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.DispatchForResponseCodeHssCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -52,24 +57,40 @@ */ @Singleton public class SignScheduleTranslator extends AbstractCallTranslator { - public static final Function SIGN_SCHEDULE = new Function("signSchedule(address,bytes)", ReturnTypes.INT_64); - public static final Function SIGN_SCHEDULE_PROXY = new Function("signSchedule()", ReturnTypes.INT_64); - public static final Function AUTHORIZE_SCHEDULE = new Function("authorizeSchedule(address)", ReturnTypes.INT_64); + public static final SystemContractMethod SIGN_SCHEDULE = SystemContractMethod.declare( + "signSchedule(address,bytes)", ReturnTypes.INT_64) + .withCategories(Category.SCHEDULE); + public static final SystemContractMethod SIGN_SCHEDULE_PROXY = SystemContractMethod.declare( + "signSchedule()", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withCategories(Category.SCHEDULE); + public static final SystemContractMethod AUTHORIZE_SCHEDULE = SystemContractMethod.declare( + "authorizeSchedule(address)", ReturnTypes.INT_64) + .withCategories(Category.SCHEDULE); @Inject - public SignScheduleTranslator() { + public SignScheduleTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HSS, systemContractMethodRegistry, contractMetrics); + + registerMethods(SIGN_SCHEDULE, AUTHORIZE_SCHEDULE, SIGN_SCHEDULE_PROXY); } @Override - public boolean matches(@NonNull final HssCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HssCallAttempt attempt) { requireNonNull(attempt); final var signScheduleEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractSignScheduleEnabled(); final var authorizeScheduleEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractAuthorizeScheduleEnabled(); - return attempt.isSelectorIfConfigEnabled(signScheduleEnabled, SIGN_SCHEDULE_PROXY) - || attempt.isSelectorIfConfigEnabled(authorizeScheduleEnabled, AUTHORIZE_SCHEDULE); + + if (attempt.isSelectorIfConfigEnabled(signScheduleEnabled, SIGN_SCHEDULE_PROXY)) + return Optional.of(SIGN_SCHEDULE_PROXY); + if (attempt.isSelectorIfConfigEnabled(authorizeScheduleEnabled, AUTHORIZE_SCHEDULE)) + return Optional.of(AUTHORIZE_SCHEDULE); + return Optional.empty(); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallAttempt.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallAttempt.java index b7557667ad4d..33817b36d9d1 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallAttempt.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallAttempt.java @@ -31,6 +31,9 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.swirlds.config.api.Configuration; import edu.umd.cs.findbugs.annotations.NonNull; @@ -73,6 +76,7 @@ public HtsCallAttempt( @NonNull final VerificationStrategies verificationStrategies, @NonNull final SystemContractGasCalculator gasCalculator, @NonNull final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, final boolean isStaticCall) { super( input, @@ -86,6 +90,7 @@ public HtsCallAttempt( gasCalculator, callTranslators, isStaticCall, + systemContractMethodRegistry, REDIRECT_FOR_TOKEN); if (isRedirect()) { this.redirectToken = linkedToken(redirectAddress); @@ -96,6 +101,11 @@ public HtsCallAttempt( (authorizingAddress != senderAddress) ? addressIdConverter.convertSender(authorizingAddress) : senderId; } + @Override + protected SystemContract systemContractKind() { + return SystemContractMethod.SystemContract.HTS; + } + @Override protected HtsCallAttempt self() { return this; diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallFactory.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallFactory.java index 6607ae0a5eb4..9fa3e858ce4e 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallFactory.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/HtsCallFactory.java @@ -27,6 +27,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallFactory; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.CallType; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; import javax.inject.Inject; @@ -44,17 +45,20 @@ public class HtsCallFactory implements CallFactory { private final CallAddressChecks addressChecks; private final VerificationStrategies verificationStrategies; private final List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry; @Inject public HtsCallFactory( @NonNull final SyntheticIds syntheticIds, @NonNull final CallAddressChecks addressChecks, @NonNull final VerificationStrategies verificationStrategies, - @NonNull @Named("HtsTranslators") final List> callTranslators) { + @NonNull @Named("HtsTranslators") final List> callTranslators, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry) { this.syntheticIds = requireNonNull(syntheticIds); this.addressChecks = requireNonNull(addressChecks); this.verificationStrategies = requireNonNull(verificationStrategies); this.callTranslators = requireNonNull(callTranslators); + this.systemContractMethodRegistry = requireNonNull(systemContractMethodRegistry); } /** @@ -93,6 +97,7 @@ public HtsCallFactory( verificationStrategies, systemContractGasCalculatorOf(frame), callTranslators, + systemContractMethodRegistry, frame.isStatic()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/airdrops/TokenAirdropTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/airdrops/TokenAirdropTranslator.java index c0cb03b4afff..0dfa7babca2d 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/airdrops/TokenAirdropTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/airdrops/TokenAirdropTranslator.java @@ -18,38 +18,53 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TokenAirdropTranslator extends AbstractCallTranslator { - public static final Function TOKEN_AIRDROP = - new Function("airdropTokens((address,(address,int64,bool)[],(address,address,int64,bool)[])[])", "(int32)"); + public static final SystemContractMethod TOKEN_AIRDROP = SystemContractMethod.declare( + "airdropTokens((address,(address,int64,bool)[],(address,address,int64,bool)[])[])", "(int32)") + .withCategories(Category.AIRDROP); private final TokenAirdropDecoder decoder; @Inject - public TokenAirdropTranslator(@NonNull final TokenAirdropDecoder decoder) { + public TokenAirdropTranslator( + @NonNull final TokenAirdropDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); requireNonNull(decoder); this.decoder = decoder; + + registerMethods(TOKEN_AIRDROP); } @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); final var airdropEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractAirdropTokensEnabled(); - return attempt.isSelectorIfConfigEnabled(airdropEnabled, TOKEN_AIRDROP); + if (!airdropEnabled) return Optional.empty(); + return attempt.isMethod(TOKEN_AIRDROP); } public static long gasRequirement( diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/allowance/GetAllowanceTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/allowance/GetAllowanceTranslator.java index 7f70aef71567..5f7e441c5fba 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/allowance/GetAllowanceTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/allowance/GetAllowanceTranslator.java @@ -16,15 +16,23 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.allowance; +import static java.util.Objects.requireNonNull; + import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.utils.ConversionUtils; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Arrays; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -37,27 +45,36 @@ public class GetAllowanceTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(GET_ALLOWANCE, ERC_GET_ALLOWANCE); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/associations/AssociationsTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/associations/AssociationsTranslator.java index a44cc64c4b14..b7a86ec04b18 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/associations/AssociationsTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/associations/AssociationsTranslator.java @@ -16,18 +16,25 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.associations; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -40,29 +47,41 @@ public class AssociationsTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); return attempt.isTokenRedirect() - ? attempt.isSelector(HRC_ASSOCIATE, HRC_DISSOCIATE) - : attempt.isSelector(ASSOCIATE_ONE, ASSOCIATE_MANY, DISSOCIATE_ONE, DISSOCIATE_MANY); + ? attempt.isMethod(HRC_ASSOCIATE, HRC_DISSOCIATE) + : attempt.isMethod(ASSOCIATE_ONE, ASSOCIATE_MANY, DISSOCIATE_ONE, DISSOCIATE_MANY); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/balanceof/BalanceOfTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/balanceof/BalanceOfTranslator.java index 21eb94220fc1..10d61000a3bd 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/balanceof/BalanceOfTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/balanceof/BalanceOfTranslator.java @@ -16,12 +16,19 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.balanceof; +import static java.util.Objects.requireNonNull; + import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,14 +40,22 @@ public class BalanceOfTranslator extends AbstractCallTranslator /** * Selector for balanceOf(address) method. */ - public static final Function BALANCE_OF = new Function("balanceOf(address)", ReturnTypes.INT); + public static final SystemContractMethod BALANCE_OF = SystemContractMethod.declare( + "balanceOf(address)", ReturnTypes.INT) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public BalanceOfTranslator() { + public BalanceOfTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(BALANCE_OF); } /** @@ -55,11 +70,9 @@ public BalanceOfCall callFrom(@NonNull final HtsCallAttempt attempt) { attempt.enhancement(), attempt.systemContractGasCalculator(), attempt.redirectToken(), owner); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(BALANCE_OF); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(BALANCE_OF); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/burn/BurnTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/burn/BurnTranslator.java index 106d80a0c420..d38bfac2fd6a 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/burn/BurnTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/burn/BurnTranslator.java @@ -18,32 +18,46 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes.INT64_INT64; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnDecoder.BURN_OUTPUT_FN; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translator class for burn calls */ +@Singleton public class BurnTranslator extends AbstractCallTranslator { /** * Selector for burnToken(address,uint64,int64[]) method. */ - public static final Function BURN_TOKEN_V1 = new Function("burnToken(address,uint64,int64[])", INT64_INT64); + public static final SystemContractMethod BURN_TOKEN_V1 = SystemContractMethod.declare( + "burnToken(address,uint64,int64[])", INT64_INT64) + .withVariant(Variant.V1) + .withCategories(Category.MINT_BURN); /** * Selector for burnToken(address,int64,int64[]) method. */ - public static final Function BURN_TOKEN_V2 = new Function("burnToken(address,int64,int64[])", INT64_INT64); + public static final SystemContractMethod BURN_TOKEN_V2 = SystemContractMethod.declare( + "burnToken(address,int64,int64[])", INT64_INT64) + .withVariant(Variant.V2) + .withCategories(Category.MINT_BURN); BurnDecoder decoder; @@ -52,13 +66,20 @@ public class BurnTranslator extends AbstractCallTranslator { * @param decoder the decoder to use for decoding burn calls */ @Inject - public BurnTranslator(@NonNull final BurnDecoder decoder) { + public BurnTranslator( + @NonNull final BurnDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(BURN_TOKEN_V1, BURN_TOKEN_V2); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { - return attempt.isSelector(BURN_TOKEN_V1, BURN_TOKEN_V2); + public @NonNull Optional identifyMethod(@NonNull HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(BURN_TOKEN_V1, BURN_TOKEN_V2); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoder.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoder.java index c684ac60dc82..1f91e80eb861 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoder.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoder.java @@ -52,7 +52,7 @@ public TokenCancelAirdropDecoder() { } public TransactionBody decodeCancelAirdrop(@NonNull final HtsCallAttempt attempt) { - final var call = TokenCancelAirdropTranslator.CANCEL_AIRDROP.decodeCall(attempt.inputBytes()); + final var call = TokenCancelAirdropTranslator.CANCEL_AIRDROPS.decodeCall(attempt.inputBytes()); final var maxPendingAirdropsToCancel = attempt.configuration().getConfigData(TokensConfig.class).maxAllowedPendingAirdropsToCancel(); final var transferList = (Tuple[]) call.get(TRANSFER_LIST); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslator.java index 3515e354776e..ece93e40be8c 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslator.java @@ -18,46 +18,71 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TokenCancelAirdropTranslator extends AbstractCallTranslator { // Actual signature definition with struct name before flattening // cancelAirdrops(PendingAirdrop[]) - public static final Function CANCEL_AIRDROP = - new Function("cancelAirdrops((address,address,address,int64)[])", ReturnTypes.INT_64); - public static final Function HRC_CANCEL_AIRDROP_FT = new Function("cancelAirdropFT(address)", ReturnTypes.INT_64); - public static final Function HRC_CANCEL_AIRDROP_NFT = - new Function("cancelAirdropNFT(address,int64)", ReturnTypes.INT_64); + public static final SystemContractMethod CANCEL_AIRDROPS = SystemContractMethod.declare( + "cancelAirdrops((address,address,address,int64)[])", ReturnTypes.INT_64) + .withCategories(Category.AIRDROP); + public static final SystemContractMethod HRC_CANCEL_AIRDROP_FT = SystemContractMethod.declare( + "cancelAirdropFT(address)", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.FT) + .withCategories(Category.AIRDROP); + public static final SystemContractMethod HRC_CANCEL_AIRDROP_NFT = SystemContractMethod.declare( + "cancelAirdropNFT(address,int64)", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.NFT) + .withCategories(Category.AIRDROP); private final TokenCancelAirdropDecoder decoder; @Inject - public TokenCancelAirdropTranslator(@NonNull final TokenCancelAirdropDecoder decoder) { + public TokenCancelAirdropTranslator( + @NonNull final TokenCancelAirdropDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); requireNonNull(decoder); this.decoder = decoder; + + registerMethods(CANCEL_AIRDROPS, HRC_CANCEL_AIRDROP_FT, HRC_CANCEL_AIRDROP_NFT); } @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); final var cancelAirdropEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractCancelAirdropsEnabled(); + + if (!cancelAirdropEnabled) return Optional.empty(); return attempt.isTokenRedirect() - ? attempt.isSelectorIfConfigEnabled(cancelAirdropEnabled, HRC_CANCEL_AIRDROP_FT, HRC_CANCEL_AIRDROP_NFT) - : attempt.isSelectorIfConfigEnabled(cancelAirdropEnabled, CANCEL_AIRDROP); + ? attempt.isMethod(HRC_CANCEL_AIRDROP_FT, HRC_CANCEL_AIRDROP_NFT) + : attempt.isMethod(CANCEL_AIRDROPS); } @Override @@ -67,7 +92,7 @@ public Call callFrom(@NonNull final HtsCallAttempt attempt) { } private TransactionBody bodyFor(@NonNull final HtsCallAttempt attempt) { - if (attempt.isSelector(CANCEL_AIRDROP)) { + if (attempt.isSelector(CANCEL_AIRDROPS)) { return decoder.decodeCancelAirdrop(attempt); } else if (attempt.isSelector(HRC_CANCEL_AIRDROP_FT)) { return decoder.decodeCancelAirdropFT(attempt); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoder.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoder.java index 8071cedf201c..08ca179755d2 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoder.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoder.java @@ -52,7 +52,7 @@ public TokenClaimAirdropDecoder() { } public TransactionBody decodeTokenClaimAirdrop(@NonNull final HtsCallAttempt attempt) { - final var call = TokenClaimAirdropTranslator.CLAIM_AIRDROP.decodeCall(attempt.inputBytes()); + final var call = TokenClaimAirdropTranslator.CLAIM_AIRDROPS.decodeCall(attempt.inputBytes()); final var maxPendingAirdropsToClaim = attempt.configuration().getConfigData(TokensConfig.class).maxAllowedPendingAirdropsToClaim(); final var transferList = (Tuple[]) call.get(TRANSFER_LIST); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslator.java index 92ae61d762f5..f0302cc30a39 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslator.java @@ -16,49 +16,76 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TokenClaimAirdropTranslator extends AbstractCallTranslator { - public static final Function CLAIM_AIRDROP = - new Function("claimAirdrops((address,address,address,int64)[])", ReturnTypes.INT_64); - public static final Function HRC_CLAIM_AIRDROP_FT = new Function("claimAirdropFT(address)", ReturnTypes.INT_64); - public static final Function HRC_CLAIM_AIRDROP_NFT = - new Function("claimAirdropNFT(address,int64)", ReturnTypes.INT_64); + public static final SystemContractMethod CLAIM_AIRDROPS = SystemContractMethod.declare( + "claimAirdrops((address,address,address,int64)[])", ReturnTypes.INT_64) + .withCategories(Category.AIRDROP); + public static final SystemContractMethod HRC_CLAIM_AIRDROP_FT = SystemContractMethod.declare( + "claimAirdropFT(address)", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.FT) + .withCategories(Category.AIRDROP); + public static final SystemContractMethod HRC_CLAIM_AIRDROP_NFT = SystemContractMethod.declare( + "claimAirdropNFT(address,int64)", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.NFT) + .withCategories(Category.AIRDROP); private final TokenClaimAirdropDecoder decoder; @Inject - public TokenClaimAirdropTranslator(@NonNull final TokenClaimAirdropDecoder decoder) { + public TokenClaimAirdropTranslator( + @NonNull final TokenClaimAirdropDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(CLAIM_AIRDROPS, HRC_CLAIM_AIRDROP_FT, HRC_CLAIM_AIRDROP_NFT); } @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); final var claimAirdropEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractClaimAirdropsEnabled(); + + if (!claimAirdropEnabled) return Optional.empty(); return attempt.isTokenRedirect() - ? attempt.isSelectorIfConfigEnabled(claimAirdropEnabled, HRC_CLAIM_AIRDROP_FT, HRC_CLAIM_AIRDROP_NFT) - : attempt.isSelectorIfConfigEnabled(claimAirdropEnabled, CLAIM_AIRDROP); + ? attempt.isMethod(HRC_CLAIM_AIRDROP_FT, HRC_CLAIM_AIRDROP_NFT) + : attempt.isMethod(CLAIM_AIRDROPS); } @Override public Call callFrom(@NonNull final HtsCallAttempt attempt) { return new DispatchForResponseCodeHtsCall( attempt, - attempt.isSelector(CLAIM_AIRDROP) ? bodyForClassic(attempt) : bodyForHRC(attempt), + attempt.isSelector(CLAIM_AIRDROPS) ? bodyForClassic(attempt) : bodyForHRC(attempt), TokenClaimAirdropTranslator::gasRequirement); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/create/CreateTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/create/CreateTranslator.java index 058906ddc1dd..6558511cb1ed 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/create/CreateTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/create/CreateTranslator.java @@ -27,147 +27,191 @@ import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.HEDERA_TOKEN_WITH_METADATA; import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.ROYALTY_FEE; import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.ROYALTY_FEE_V2; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.HashMap; import java.util.Map; -import java.util.Set; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code createFungibleToken}, {@code createNonFungibleToken}, * {@code createFungibleTokenWithCustomFees} and {@code createNonFungibleTokenWithCustomFees} calls to the HTS system contract. */ +@Singleton public class CreateTranslator extends AbstractCallTranslator { /** Selector for createFungibleToken(HEDERA_TOKEN_V1,uint,uint) method. */ - public static final Function CREATE_FUNGIBLE_TOKEN_V1 = - new Function("createFungibleToken(" + HEDERA_TOKEN_V1 + ",uint,uint)", "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_TOKEN_V1 = SystemContractMethod.declare( + "createFungibleToken(" + HEDERA_TOKEN_V1 + ",uint,uint)", "(int64,address)") + .withVariants(Variant.V1, Variant.FT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleToken(HEDERA_TOKEN_V2,uint64,uint32) method. */ - public static final Function CREATE_FUNGIBLE_TOKEN_V2 = - new Function("createFungibleToken(" + HEDERA_TOKEN_V2 + ",uint64,uint32)", "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_TOKEN_V2 = SystemContractMethod.declare( + "createFungibleToken(" + HEDERA_TOKEN_V2 + ",uint64,uint32)", "(int64,address)") + .withVariants(Variant.V2, Variant.FT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleToken(HEDERA_TOKEN_V3,int64,int32) method. */ - public static final Function CREATE_FUNGIBLE_TOKEN_V3 = - new Function("createFungibleToken(" + HEDERA_TOKEN_V3 + ",int64,int32)", "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_TOKEN_V3 = SystemContractMethod.declare( + "createFungibleToken(" + HEDERA_TOKEN_V3 + ",int64,int32)", "(int64,address)") + .withVariants(Variant.V3, Variant.FT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleTokenWithCustomFees(HEDERA_TOKEN_V1,uint,uint,FIXED_FEE[],FRACTIONAL_FEE[]) method. */ - public static final Function CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V1 = new Function( - "createFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V1 - + ",uint,uint," - + FIXED_FEE - + ARRAY_BRACKETS - + "," - + FRACTIONAL_FEE - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V1 = SystemContractMethod.declare( + "createFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V1 + + ",uint,uint," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + FRACTIONAL_FEE + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V1, Variant.FT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleTokenWithCustomFees(HEDERA_TOKEN_V2,uint64,uint32,FIXED_FEE[],FRACTIONAL_FEE[]) method. */ - public static final Function CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V2 = new Function( - "createFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V2 - + ",uint64,uint32," - + FIXED_FEE - + ARRAY_BRACKETS - + "," - + FRACTIONAL_FEE - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V2 = SystemContractMethod.declare( + "createFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V2 + + ",uint64,uint32," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + FRACTIONAL_FEE + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V2, Variant.FT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleTokenWithCustomFees(HEDERA_TOKEN_V3,int64,int32,FIXED_FEE_V2[],FRACTIONAL_FEE_V2[]) method. */ - public static final Function CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V3 = new Function( - "createFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V3 - + ",int64,int32," - + FIXED_FEE_V2 - + ARRAY_BRACKETS - + "," - + FRACTIONAL_FEE_V2 - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V3 = SystemContractMethod.declare( + "createFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V3 + + ",int64,int32," + + FIXED_FEE_V2 + + ARRAY_BRACKETS + + "," + + FRACTIONAL_FEE_V2 + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V3, Variant.FT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleToken(HEDERA_TOKEN_V1) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_V1 = - new Function("createNonFungibleToken(" + HEDERA_TOKEN_V1 + ")", "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_V1 = SystemContractMethod.declare( + "createNonFungibleToken(" + HEDERA_TOKEN_V1 + ")", "(int64,address)") + .withVariants(Variant.V1, Variant.NFT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleToken(HEDERA_TOKEN_V2) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_V2 = - new Function("createNonFungibleToken(" + HEDERA_TOKEN_V2 + ")", "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_V2 = SystemContractMethod.declare( + "createNonFungibleToken(" + HEDERA_TOKEN_V2 + ")", "(int64,address)") + .withVariants(Variant.V2, Variant.NFT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleToken(HEDERA_TOKEN_V3) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_V3 = - new Function("createNonFungibleToken(" + HEDERA_TOKEN_V3 + ")", "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_V3 = SystemContractMethod.declare( + "createNonFungibleToken(" + HEDERA_TOKEN_V3 + ")", "(int64,address)") + .withVariants(Variant.V3, Variant.NFT) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleTokenWithCustomFees(HEDERA_TOKEN_V1,int64,int32,FIXED_FEE[],FRACTIONAL_FEE[]) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V1 = new Function( - "createNonFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V1 - + "," - + FIXED_FEE - + ARRAY_BRACKETS - + "," - + ROYALTY_FEE - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V1 = + SystemContractMethod.declare( + "createNonFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V1 + + "," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + ROYALTY_FEE + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V1, Variant.NFT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleTokenWithCustomFees(HEDERA_TOKEN_V2,int64,int32,FIXED_FEE[],FRACTIONAL_FEE[]) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V2 = new Function( - "createNonFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V2 - + "," - + FIXED_FEE - + ARRAY_BRACKETS - + "," - + ROYALTY_FEE - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V2 = + SystemContractMethod.declare( + "createNonFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V2 + + "," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + ROYALTY_FEE + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V2, Variant.NFT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleTokenWithCustomFees(HEDERA_TOKEN_V3,int64,int32,FIXED_FEE_2[],FRACTIONAL_FEE_2[]) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V3 = new Function( - "createNonFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_V3 - + "," - + FIXED_FEE_V2 - + ARRAY_BRACKETS - + "," - + ROYALTY_FEE_V2 - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V3 = + SystemContractMethod.declare( + "createNonFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_V3 + + "," + + FIXED_FEE_V2 + + ARRAY_BRACKETS + + "," + + ROYALTY_FEE_V2 + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.V3, Variant.NFT, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleTokenWithCustomFees(HEDERA_TOKEN_WITH_METADATA,int64,int32) method. */ - public static final Function CREATE_FUNGIBLE_TOKEN_WITH_METADATA = - new Function("createFungibleToken(" + HEDERA_TOKEN_WITH_METADATA + ",int64,int32)", "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_TOKEN_WITH_METADATA = SystemContractMethod.declare( + "createFungibleToken(" + HEDERA_TOKEN_WITH_METADATA + ",int64,int32)", "(int64,address)") + .withVariants(Variant.FT, Variant.WITH_METADATA) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createFungibleTokenWithCustomFees(HEDERA_TOKEN_WITH_METADATA,int64,int32,FIXED_FEE_2[],FRACTIONAL_FEE_2[]) method. */ - public static final Function CREATE_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES = new Function( - "createFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_WITH_METADATA - + ",int64,int32," - + FIXED_FEE_V2 - + ARRAY_BRACKETS - + "," - + FRACTIONAL_FEE_V2 - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES = + SystemContractMethod.declare( + "createFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_WITH_METADATA + + ",int64,int32," + + FIXED_FEE_V2 + + ARRAY_BRACKETS + + "," + + FRACTIONAL_FEE_V2 + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.FT, Variant.WITH_METADATA, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleToken(HEDERA_TOKEN_WITH_METADATA) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA = - new Function("createNonFungibleToken(" + HEDERA_TOKEN_WITH_METADATA + ")", "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA = SystemContractMethod.declare( + "createNonFungibleToken(" + HEDERA_TOKEN_WITH_METADATA + ")", "(int64,address)") + .withVariants(Variant.NFT, Variant.WITH_METADATA) + .withCategory(Category.CREATE_DELETE_TOKEN); /** Selector for createNonFungibleTokenWithCustomFees(HEDERA_TOKEN_WITH_METADATA,FIXED_FEE_2[],FRACTIONAL_FEE_2[]) method. */ - public static final Function CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES = new Function( - "createNonFungibleTokenWithCustomFees(" - + HEDERA_TOKEN_WITH_METADATA - + "," - + FIXED_FEE_V2 - + ARRAY_BRACKETS - + "," - + ROYALTY_FEE_V2 - + ARRAY_BRACKETS - + ")", - "(int64,address)"); + public static final SystemContractMethod CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES = + SystemContractMethod.declare( + "createNonFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_WITH_METADATA + + "," + + FIXED_FEE_V2 + + ARRAY_BRACKETS + + "," + + ROYALTY_FEE_V2 + + ARRAY_BRACKETS + + ")", + "(int64,address)") + .withVariants(Variant.NFT, Variant.WITH_METADATA, Variant.WITH_CUSTOM_FEES) + .withCategory(Category.CREATE_DELETE_TOKEN); /** * A set of `Function` objects representing various create functions for fungible and non-fungible tokens. @@ -175,52 +219,76 @@ public class CreateTranslator extends AbstractCallTranslator { * to determine if a given call attempt is a creation call, because we do not allow sending value to Hedera system contracts * except in the case of token creation */ - public static final Map createSelectorsMap = new HashMap<>(); + public static final Map createMethodsMap = new HashMap<>(); /** * Constructor for injection. * @param decoder the decoder used to decode create calls */ @Inject - public CreateTranslator(final CreateDecoder decoder) { - createSelectorsMap.put(CREATE_FUNGIBLE_TOKEN_V1, decoder::decodeCreateFungibleTokenV1); - createSelectorsMap.put(CREATE_FUNGIBLE_TOKEN_V2, decoder::decodeCreateFungibleTokenV2); - createSelectorsMap.put(CREATE_FUNGIBLE_TOKEN_V3, decoder::decodeCreateFungibleTokenV3); - createSelectorsMap.put(CREATE_FUNGIBLE_TOKEN_WITH_METADATA, decoder::decodeCreateFungibleTokenWithMetadata); - createSelectorsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V1, decoder::decodeCreateFungibleTokenWithCustomFeesV1); - createSelectorsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V2, decoder::decodeCreateFungibleTokenWithCustomFeesV2); - createSelectorsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V3, decoder::decodeCreateFungibleTokenWithCustomFeesV3); - createSelectorsMap.put( + public CreateTranslator( + final CreateDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods( + CREATE_FUNGIBLE_TOKEN_V1, + CREATE_FUNGIBLE_TOKEN_V2, + CREATE_FUNGIBLE_TOKEN_V3, + CREATE_FUNGIBLE_TOKEN_WITH_METADATA, + CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V1, + CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V2, + CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V3, + CREATE_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES, + CREATE_NON_FUNGIBLE_TOKEN_V1, + CREATE_NON_FUNGIBLE_TOKEN_V2, + CREATE_NON_FUNGIBLE_TOKEN_V3, + CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA, + CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V1, + CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V2, + CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V3, + CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES); + + createMethodsMap.put(CREATE_FUNGIBLE_TOKEN_V1, decoder::decodeCreateFungibleTokenV1); + createMethodsMap.put(CREATE_FUNGIBLE_TOKEN_V2, decoder::decodeCreateFungibleTokenV2); + createMethodsMap.put(CREATE_FUNGIBLE_TOKEN_V3, decoder::decodeCreateFungibleTokenV3); + createMethodsMap.put(CREATE_FUNGIBLE_TOKEN_WITH_METADATA, decoder::decodeCreateFungibleTokenWithMetadata); + createMethodsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V1, decoder::decodeCreateFungibleTokenWithCustomFeesV1); + createMethodsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V2, decoder::decodeCreateFungibleTokenWithCustomFeesV2); + createMethodsMap.put(CREATE_FUNGIBLE_WITH_CUSTOM_FEES_V3, decoder::decodeCreateFungibleTokenWithCustomFeesV3); + createMethodsMap.put( CREATE_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES, decoder::decodeCreateFungibleTokenWithMetadataAndCustomFees); - createSelectorsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V1, decoder::decodeCreateNonFungibleV1); - createSelectorsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V2, decoder::decodeCreateNonFungibleV2); - createSelectorsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V3, decoder::decodeCreateNonFungibleV3); - createSelectorsMap.put(CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA, decoder::decodeCreateNonFungibleWithMetadata); - createSelectorsMap.put( + createMethodsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V1, decoder::decodeCreateNonFungibleV1); + createMethodsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V2, decoder::decodeCreateNonFungibleV2); + createMethodsMap.put(CREATE_NON_FUNGIBLE_TOKEN_V3, decoder::decodeCreateNonFungibleV3); + createMethodsMap.put(CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA, decoder::decodeCreateNonFungibleWithMetadata); + createMethodsMap.put( CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V1, decoder::decodeCreateNonFungibleWithCustomFeesV1); - createSelectorsMap.put( + createMethodsMap.put( CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V2, decoder::decodeCreateNonFungibleWithCustomFeesV2); - createSelectorsMap.put( + createMethodsMap.put( CREATE_NON_FUNGIBLE_TOKEN_WITH_CUSTOM_FEES_V3, decoder::decodeCreateNonFungibleWithCustomFeesV3); - createSelectorsMap.put( + createMethodsMap.put( CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES, decoder::decodeCreateNonFungibleWithMetadataAndCustomFees); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull HtsCallAttempt attempt) { + requireNonNull(attempt); final var metaConfigEnabled = attempt.configuration().getConfigData(ContractsConfig.class).metadataKeyAndFieldEnabled(); - final var metaSelectors = Set.of( - CREATE_FUNGIBLE_TOKEN_WITH_METADATA, - CREATE_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES, - CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA, - CREATE_NON_FUNGIBLE_TOKEN_WITH_METADATA_AND_CUSTOM_FEES); - return createSelectorsMap.keySet().stream() - .anyMatch(selector -> metaSelectors.contains(selector) - ? attempt.isSelectorIfConfigEnabled(metaConfigEnabled, selector) - : attempt.isSelector(selector)); + + for (final var method : createMethodsMap.keySet()) { + final var isMetadataMethod = method.hasVariant(Variant.WITH_METADATA); + Optional m = isMetadataMethod + ? metaConfigEnabled ? attempt.isMethod(method) : Optional.empty() + : attempt.isMethod(method); + if (m.isPresent()) return m; + } + return Optional.empty(); } @Override @@ -239,7 +307,7 @@ public ClassicCreatesCall callFrom(@NonNull HtsCallAttempt attempt) { final var nativeOperations = attempt.nativeOperations(); final var addressIdConverter = attempt.addressIdConverter(); - return createSelectorsMap.entrySet().stream() + return createMethodsMap.entrySet().stream() .filter(entry -> attempt.isSelector(entry.getKey())) .map(entry -> entry.getValue().decode(inputBytes, senderId, nativeOperations, addressIdConverter)) .findFirst() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslator.java index 0b81af6212e9..eb77d3895afb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslator.java @@ -17,31 +17,46 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.customfees; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class TokenCustomFeesTranslator extends AbstractCallTranslator { - public static final Function TOKEN_CUSTOM_FEES = - new Function("getTokenCustomFees(address)", ReturnTypes.RESPONSE_CODE_CUSTOM_FEES); + public static final SystemContractMethod TOKEN_CUSTOM_FEES = SystemContractMethod.declare( + "getTokenCustomFees(address)", ReturnTypes.RESPONSE_CODE_CUSTOM_FEES) + .withModifier(Modifier.VIEW) + .withVariant(Variant.WITH_CUSTOM_FEES) + .withCategory(Category.TOKEN_QUERY); @Inject - public TokenCustomFeesTranslator() { + public TokenCustomFeesTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_CUSTOM_FEES); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_CUSTOM_FEES); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(TOKEN_CUSTOM_FEES); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/decimals/DecimalsTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/decimals/DecimalsTranslator.java index cf8f65fe0a3d..99d676d51856 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/decimals/DecimalsTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/decimals/DecimalsTranslator.java @@ -16,12 +16,19 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.decimals; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -31,22 +38,27 @@ @Singleton public class DecimalsTranslator extends AbstractCallTranslator { /** Selector for updateTokenKeys(address, TOKEN_KEY[]) method. */ - public static final Function DECIMALS = new Function("decimals()", ReturnTypes.BYTE); + public static final SystemContractMethod DECIMALS = SystemContractMethod.declare("decimals()", ReturnTypes.BYTE) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public DecimalsTranslator() { + public DecimalsTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(DECIMALS); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(DECIMALS); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(DECIMALS); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslator.java index cc1d75cca579..49fb4ef6807f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslator.java @@ -17,37 +17,50 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultfreezestatus; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenDefaultFreezeStatus()} calls to the HTS system contract. */ +@Singleton public class DefaultFreezeStatusTranslator extends AbstractCallTranslator { /** Selector for getTokenDefaultFreezeStatus(address) method. */ - public static final Function DEFAULT_FREEZE_STATUS = - new Function("getTokenDefaultFreezeStatus(address)", ReturnTypes.RESPONSE_CODE_BOOL); + public static final SystemContractMethod DEFAULT_FREEZE_STATUS = SystemContractMethod.declare( + "getTokenDefaultFreezeStatus(address)", ReturnTypes.RESPONSE_CODE_BOOL) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public DefaultFreezeStatusTranslator() { + public DefaultFreezeStatusTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(DEFAULT_FREEZE_STATUS); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(DEFAULT_FREEZE_STATUS); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(DEFAULT_FREEZE_STATUS); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslator.java index 58a51c41a9af..02e958e7607d 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslator.java @@ -17,37 +17,50 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultkycstatus; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenDefaultKycStatus()} calls to the HTS system contract. */ +@Singleton public class DefaultKycStatusTranslator extends AbstractCallTranslator { /** Selector for getTokenDefaultKycStatus(address) method. */ - public static final Function DEFAULT_KYC_STATUS = - new Function("getTokenDefaultKycStatus(address)", ReturnTypes.RESPONSE_CODE_BOOL); + public static final SystemContractMethod DEFAULT_KYC_STATUS = SystemContractMethod.declare( + "getTokenDefaultKycStatus(address)", ReturnTypes.RESPONSE_CODE_BOOL) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public DefaultKycStatusTranslator() { + public DefaultKycStatusTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(DEFAULT_KYC_STATUS); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(DEFAULT_KYC_STATUS); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(DEFAULT_KYC_STATUS); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/delete/DeleteTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/delete/DeleteTranslator.java index cd764819e3a3..400c288fac1d 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/delete/DeleteTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/delete/DeleteTranslator.java @@ -16,40 +16,56 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.delete; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.token.TokenDeleteTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.utils.ConversionUtils; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code delete} calls to the HTS system contract. */ +@Singleton public class DeleteTranslator extends AbstractCallTranslator { /** Selector for deleteToken(address) method. */ - public static final Function DELETE_TOKEN = new Function("deleteToken(address)", ReturnTypes.INT); + public static final SystemContractMethod DELETE_TOKEN = SystemContractMethod.declare( + "deleteToken(address)", ReturnTypes.INT) + .withCategories(Category.CREATE_DELETE_TOKEN); /** * Default constructor to delete. */ @Inject - public DeleteTranslator() { + public DeleteTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(DELETE_TOKEN); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { - return attempt.isSelector(DELETE_TOKEN); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(DELETE_TOKEN); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslator.java index de0989201d0e..2a8223939470 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslator.java @@ -17,20 +17,25 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall.FailureCustomizer.NOOP_CUSTOMIZER; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Arrays; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -40,9 +45,13 @@ @Singleton public class FreezeUnfreezeTranslator extends AbstractCallTranslator { /** Selector for freezeToken(address,address) method. */ - public static final Function FREEZE = new Function("freezeToken(address,address)", ReturnTypes.INT_64); + public static final SystemContractMethod FREEZE = SystemContractMethod.declare( + "freezeToken(address,address)", ReturnTypes.INT_64) + .withCategories(Category.FREEZE_UNFREEZE); /** Selector for unfreezeToken(address,address) method. */ - public static final Function UNFREEZE = new Function("unfreezeToken(address,address)", ReturnTypes.INT_64); + public static final SystemContractMethod UNFREEZE = SystemContractMethod.declare( + "unfreezeToken(address,address)", ReturnTypes.INT_64) + .withCategories(Category.FREEZE_UNFREEZE); private final FreezeUnfreezeDecoder decoder; @@ -50,16 +59,20 @@ public class FreezeUnfreezeTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(FREEZE, UNFREEZE); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCall.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCall.java index 69fa08c2b07c..1243442dd7a6 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCall.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCall.java @@ -84,7 +84,7 @@ public FungibleTokenInfoCall( return revertResult(status, gasRequirement); } - return function.getName().equals(FUNGIBLE_TOKEN_INFO.getName()) + return function.getName().equals(FUNGIBLE_TOKEN_INFO.methodName()) ? successResult( FUNGIBLE_TOKEN_INFO .getOutputs() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslator.java index 6ace95c8ab34..d5b4c20cbde9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslator.java @@ -19,43 +19,60 @@ import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class FungibleTokenInfoTranslator extends AbstractCallTranslator { /** Selector for getFungibleTokenInfo(address) method. */ - public static final Function FUNGIBLE_TOKEN_INFO = - new Function("getFungibleTokenInfo(address)", ReturnTypes.RESPONSE_CODE_FUNGIBLE_TOKEN_INFO); + public static final SystemContractMethod FUNGIBLE_TOKEN_INFO = SystemContractMethod.declare( + "getFungibleTokenInfo(address)", ReturnTypes.RESPONSE_CODE_FUNGIBLE_TOKEN_INFO) + .withVariants(Variant.V1, Variant.FT) + .withCategory(Category.TOKEN_QUERY); /** Selector for getFungibleTokenInfoV2(address) method. */ - public static final Function FUNGIBLE_TOKEN_INFO_V2 = - new Function("getFungibleTokenInfoV2(address)", ReturnTypes.RESPONSE_CODE_FUNGIBLE_TOKEN_INFO_V2); + public static final SystemContractMethod FUNGIBLE_TOKEN_INFO_V2 = SystemContractMethod.declare( + "getFungibleTokenInfoV2(address)", ReturnTypes.RESPONSE_CODE_FUNGIBLE_TOKEN_INFO_V2) + .withVariants(Variant.V2, Variant.FT) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public FungibleTokenInfoTranslator() { + public FungibleTokenInfoTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(FUNGIBLE_TOKEN_INFO, FUNGIBLE_TOKEN_INFO_V2); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); + final var v2Enabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractTokenInfoV2Enabled(); - return attempt.isSelector(FUNGIBLE_TOKEN_INFO) - || attempt.isSelectorIfConfigEnabled(v2Enabled, FUNGIBLE_TOKEN_INFO_V2); + + if (attempt.isMethod(FUNGIBLE_TOKEN_INFO).isPresent()) return Optional.of(FUNGIBLE_TOKEN_INFO); + if (attempt.isSelectorIfConfigEnabled(v2Enabled, FUNGIBLE_TOKEN_INFO_V2)) + return Optional.of(FUNGIBLE_TOKEN_INFO_V2); + return Optional.empty(); } /** @@ -64,8 +81,8 @@ public boolean matches(@NonNull final HtsCallAttempt attempt) { @Override public Call callFrom(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); - final var function = attempt.isSelector(FUNGIBLE_TOKEN_INFO) ? FUNGIBLE_TOKEN_INFO : FUNGIBLE_TOKEN_INFO_V2; - final var args = function.decodeCall(attempt.input().toArrayUnsafe()); + final var method = attempt.isSelector(FUNGIBLE_TOKEN_INFO) ? FUNGIBLE_TOKEN_INFO : FUNGIBLE_TOKEN_INFO_V2; + final var args = method.decodeCall(attempt.input().toArrayUnsafe()); final var token = attempt.linkedToken(fromHeadlongAddress(args.get(0))); return new FungibleTokenInfoCall( attempt.systemContractGasCalculator(), @@ -73,6 +90,6 @@ public Call callFrom(@NonNull final HtsCallAttempt attempt) { attempt.isStaticCall(), token, attempt.configuration(), - function); + method.function()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/getapproved/GetApprovedTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/getapproved/GetApprovedTranslator.java index 0b6bb0eee6cf..9b0f574b4d32 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/getapproved/GetApprovedTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/getapproved/GetApprovedTranslator.java @@ -18,12 +18,19 @@ import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asExactLongValueOrZero; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -34,24 +41,35 @@ public class GetApprovedTranslator extends AbstractCallTranslator { /** Selector for getApproved(address,uint256) method. */ - public static final Function HAPI_GET_APPROVED = new Function("getApproved(address,uint256)", "(int32,address)"); + public static final SystemContractMethod HAPI_GET_APPROVED = SystemContractMethod.declare( + "getApproved(address,uint256)", "(int32,address)") + .withModifier(Modifier.VIEW) + .withCategories(Category.TOKEN_QUERY, Category.APPROVAL); /** Selector for getApproved(uint256) method. */ - public static final Function ERC_GET_APPROVED = new Function("getApproved(uint256)", ReturnTypes.ADDRESS); + public static final SystemContractMethod ERC_GET_APPROVED = SystemContractMethod.declare( + "getApproved(uint256)", ReturnTypes.ADDRESS) + .withVia(CallVia.PROXY) + .withModifier(Modifier.VIEW) + .withCategories(Category.ERC721, Category.TOKEN_QUERY, Category.APPROVAL); /** * Default constructor for injection. */ @Inject - public GetApprovedTranslator() { + public GetApprovedTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(HAPI_GET_APPROVED, ERC_GET_APPROVED); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isTokenRedirect() ? attempt.isSelector(ERC_GET_APPROVED) : attempt.isSelector(HAPI_GET_APPROVED); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + + return attempt.isTokenRedirect() ? attempt.isMethod(ERC_GET_APPROVED) : attempt.isMethod(HAPI_GET_APPROVED); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslator.java index 8892d642a519..833460e2d283 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslator.java @@ -19,21 +19,27 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.TokenType; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.utils.ConversionUtils; import edu.umd.cs.findbugs.annotations.NonNull; import java.math.BigInteger; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -44,14 +50,27 @@ public class GrantApprovalTranslator extends AbstractCallTranslator { /** Selector for approve(address,uint256) method. */ - public static final Function ERC_GRANT_APPROVAL = new Function("approve(address,uint256)", ReturnTypes.BOOL); + public static final SystemContractMethod ERC_GRANT_APPROVAL = SystemContractMethod.declare( + "approve(address,uint256)", ReturnTypes.BOOL) + .withVia(CallVia.PROXY) + .withVariant(Variant.FT) + .withCategories(Category.ERC20, Category.APPROVAL); /** Selector for approve(address,uint256) method. */ - public static final Function ERC_GRANT_APPROVAL_NFT = new Function("approve(address,uint256)"); + public static final SystemContractMethod ERC_GRANT_APPROVAL_NFT = SystemContractMethod.declare( + "approve(address,uint256)") + .withVia(CallVia.PROXY) + .withVariant(Variant.NFT) + .withCategories(Category.ERC721, Category.APPROVAL); /** Selector for approve(address,address,uint256) method. */ - public static final Function GRANT_APPROVAL = new Function("approve(address,address,uint256)", "(int32,bool)"); + public static final SystemContractMethod GRANT_APPROVAL = SystemContractMethod.declare( + "approve(address,address,uint256)", "(int32,bool)") + .withVariant(Variant.FT) + .withCategories(Category.ERC721, Category.APPROVAL); /** Selector for approveNFT(address,address,uint256) method. */ - public static final Function GRANT_APPROVAL_NFT = - new Function("approveNFT(address,address,uint256)", ReturnTypes.INT_64); + public static final SystemContractMethod GRANT_APPROVAL_NFT = SystemContractMethod.declare( + "approveNFT(address,address,uint256)", ReturnTypes.INT_64) + .withVariant(Variant.NFT) + .withCategories(Category.APPROVAL); private final GrantApprovalDecoder decoder; @@ -60,16 +79,20 @@ public class GrantApprovalTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(GRANT_APPROVAL, GRANT_APPROVAL_NFT, ERC_GRANT_APPROVAL); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslator.java index 14db3f20a93e..90012f09a0b3 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslator.java @@ -17,17 +17,22 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantrevokekyc; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall.FailureCustomizer.NOOP_CUSTOMIZER; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.*; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -40,11 +45,15 @@ public class GrantRevokeKycTranslator extends AbstractCallTranslator identifyMethod(@NonNull HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(GRANT_KYC, REVOKE_KYC); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isapprovedforall/IsApprovedForAllTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isapprovedforall/IsApprovedForAllTranslator.java index 67d087ad4b90..e67e30c06dff 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isapprovedforall/IsApprovedForAllTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isapprovedforall/IsApprovedForAllTranslator.java @@ -17,11 +17,17 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isapprovedforall; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -31,25 +37,32 @@ @Singleton public class IsApprovedForAllTranslator extends AbstractCallTranslator { /** Selector for isApprovedForAll(address,address,address) method. */ - public static final Function CLASSIC_IS_APPROVED_FOR_ALL = - new Function("isApprovedForAll(address,address,address)", "(int64,bool)"); + public static final SystemContractMethod CLASSIC_IS_APPROVED_FOR_ALL = SystemContractMethod.declare( + "isApprovedForAll(address,address,address)", "(int64,bool)") + .withCategories(Category.TOKEN_QUERY, Category.APPROVAL); /** Selector for isApprovedForAll(address,address) method. */ - public static final Function ERC_IS_APPROVED_FOR_ALL = new Function("isApprovedForAll(address,address)", "(bool)"); + public static final SystemContractMethod ERC_IS_APPROVED_FOR_ALL = SystemContractMethod.declare( + "isApprovedForAll(address,address)", "(bool)") + .withVia(CallVia.PROXY) + .withCategories(Category.TOKEN_QUERY, Category.APPROVAL); /** * Default constructor for injection. */ @Inject - public IsApprovedForAllTranslator() { + public IsApprovedForAllTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(CLASSIC_IS_APPROVED_FOR_ALL, ERC_IS_APPROVED_FOR_ALL); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(CLASSIC_IS_APPROVED_FOR_ALL, ERC_IS_APPROVED_FOR_ALL); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(CLASSIC_IS_APPROVED_FOR_ALL, ERC_IS_APPROVED_FOR_ALL); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isassociated/IsAssociatedTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isassociated/IsAssociatedTranslator.java index 01b61a4449a9..1a49f4dcb3d2 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isassociated/IsAssociatedTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isassociated/IsAssociatedTranslator.java @@ -18,31 +18,46 @@ import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @Singleton public class IsAssociatedTranslator extends AbstractCallTranslator { /** Selector for isAssociated() method. */ - public static final Function IS_ASSOCIATED = new Function("isAssociated()", ReturnTypes.BOOL); + public static final SystemContractMethod IS_ASSOCIATED = SystemContractMethod.declare( + "isAssociated()", ReturnTypes.BOOL) + .withModifier(Modifier.VIEW) + .withCategories(Category.TOKEN_QUERY, Category.ASSOCIATION); /** * Default constructor for injection. */ @Inject - public IsAssociatedTranslator() { + public IsAssociatedTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(IS_ASSOCIATED); } @Override - public final boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isTokenRedirect() && attempt.isSelector(IS_ASSOCIATED); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + if (!attempt.isTokenRedirect()) return Optional.empty(); + return attempt.isMethod(IS_ASSOCIATED); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isfrozen/IsFrozenTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isfrozen/IsFrozenTranslator.java index e6e887e20435..de238ec671ef 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isfrozen/IsFrozenTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/isfrozen/IsFrozenTranslator.java @@ -17,33 +17,47 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isfrozen; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class IsFrozenTranslator extends AbstractCallTranslator { /** Selector for isFrozen(address,address) method. */ - public static final Function IS_FROZEN = new Function("isFrozen(address,address)", ReturnTypes.RESPONSE_CODE_BOOL); + public static final SystemContractMethod IS_FROZEN = SystemContractMethod.declare( + "isFrozen(address,address)", ReturnTypes.RESPONSE_CODE_BOOL) + .withModifier(Modifier.VIEW) + .withCategories(Category.TOKEN_QUERY, Category.FREEZE_UNFREEZE); /** * Default constructor for injection. */ @Inject - public IsFrozenTranslator() { + public IsFrozenTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(IS_FROZEN); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(IS_FROZEN); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(IS_FROZEN); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/iskyc/IsKycTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/iskyc/IsKycTranslator.java index 565dd9ede328..4a8c9ef86db5 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/iskyc/IsKycTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/iskyc/IsKycTranslator.java @@ -17,33 +17,47 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.iskyc; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class IsKycTranslator extends AbstractCallTranslator { /** Selector for isKyc(address,address) method. */ - public static final Function IS_KYC = new Function("isKyc(address,address)", ReturnTypes.RESPONSE_CODE_BOOL); + public static final SystemContractMethod IS_KYC = SystemContractMethod.declare( + "isKyc(address,address)", ReturnTypes.RESPONSE_CODE_BOOL) + .withModifier(Modifier.VIEW) + .withCategories(Category.TOKEN_QUERY, Category.KYC); /** * Default constructor for injection. */ @Inject - public IsKycTranslator() { + public IsKycTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(IS_KYC); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(IS_KYC); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(IS_KYC); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/istoken/IsTokenTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/istoken/IsTokenTranslator.java index e91401ee4e48..3e40f17446ae 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/istoken/IsTokenTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/istoken/IsTokenTranslator.java @@ -17,33 +17,47 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.istoken; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class IsTokenTranslator extends AbstractCallTranslator { /** Selector for isToken(address) method. */ - public static final Function IS_TOKEN = new Function("isToken(address)", ReturnTypes.RESPONSE_CODE_BOOL); + public static final SystemContractMethod IS_TOKEN = SystemContractMethod.declare( + "isToken(address)", ReturnTypes.RESPONSE_CODE_BOOL) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public IsTokenTranslator() { + public IsTokenTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(IS_TOKEN); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(IS_TOKEN); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(IS_TOKEN); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/mint/MintTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/mint/MintTranslator.java index 64a127958b57..0699fe0dad25 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/mint/MintTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/mint/MintTranslator.java @@ -17,18 +17,24 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintDecoder.MINT_OUTPUT_FN; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -38,9 +44,15 @@ @Singleton public class MintTranslator extends AbstractCallTranslator { /** Selector for mintToken(address,uint64,bytes[]) method. */ - public static final Function MINT = new Function("mintToken(address,uint64,bytes[])", "(int64,int64,int64[])"); + public static final SystemContractMethod MINT = SystemContractMethod.declare( + "mintToken(address,uint64,bytes[])", "(int64,int64,int64[])") + .withVariant(Variant.V1) + .withCategories(Category.MINT_BURN); /** Selector for mintToken(address,int64,bytes[]) method. */ - public static final Function MINT_V2 = new Function("mintToken(address,int64,bytes[])", "(int64,int64,int64[])"); + public static final SystemContractMethod MINT_V2 = SystemContractMethod.declare( + "mintToken(address,int64,bytes[])", "(int64,int64,int64[])") + .withVariant(Variant.V2) + .withCategories(Category.MINT_BURN); private final MintDecoder decoder; @@ -48,16 +60,20 @@ public class MintTranslator extends AbstractCallTranslator { * @param decoder the decoder to use for mint calls */ @Inject - public MintTranslator(@NonNull final MintDecoder decoder) { + public MintTranslator( + @NonNull final MintDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(MINT, MINT_V2); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(MINT, MINT_V2); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(MINT, MINT_V2); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/name/NameTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/name/NameTranslator.java index fd153112ca0c..df709b02bfac 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/name/NameTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/name/NameTranslator.java @@ -16,11 +16,18 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.name; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -30,22 +37,27 @@ @Singleton public class NameTranslator extends AbstractCallTranslator { /** Selector for name() method. */ - public static final Function NAME = new Function("name()", ReturnTypes.STRING); + public static final SystemContractMethod NAME = SystemContractMethod.declare("name()", ReturnTypes.STRING) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public NameTranslator() { + public NameTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(NAME); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(NAME); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(NAME); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCall.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCall.java index e24bdb55c558..d8b240df538b 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCall.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCall.java @@ -98,7 +98,7 @@ public NftTokenInfoCall( final var ledgerConfig = configuration.getConfigData(LedgerConfig.class); final var ledgerId = Bytes.wrap(ledgerConfig.id().toByteArray()).toString(); - return function.getName().equals(NON_FUNGIBLE_TOKEN_INFO.getName()) + return function.getName().equals(NON_FUNGIBLE_TOKEN_INFO.methodName()) ? successResult( NON_FUNGIBLE_TOKEN_INFO .getOutputs() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslator.java index b6468797c7f3..31b4aa55a162 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslator.java @@ -19,43 +19,58 @@ import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class NftTokenInfoTranslator extends AbstractCallTranslator { /** Selector for getNonFungibleTokenInfo(address,int64) method. */ - public static final Function NON_FUNGIBLE_TOKEN_INFO = - new Function("getNonFungibleTokenInfo(address,int64)", ReturnTypes.RESPONSE_CODE_NON_FUNGIBLE_TOKEN_INFO); + public static final SystemContractMethod NON_FUNGIBLE_TOKEN_INFO = SystemContractMethod.declare( + "getNonFungibleTokenInfo(address,int64)", ReturnTypes.RESPONSE_CODE_NON_FUNGIBLE_TOKEN_INFO) + .withVariants(Variant.V1, Variant.NFT) + .withCategory(Category.TOKEN_QUERY); /** Selector for getNonFungibleTokenInfoV2(address,int64) method. */ - public static final Function NON_FUNGIBLE_TOKEN_INFO_V2 = new Function( - "getNonFungibleTokenInfoV2(address,int64)", ReturnTypes.RESPONSE_CODE_NON_FUNGIBLE_TOKEN_INFO_V2); + public static final SystemContractMethod NON_FUNGIBLE_TOKEN_INFO_V2 = SystemContractMethod.declare( + "getNonFungibleTokenInfoV2(address,int64)", ReturnTypes.RESPONSE_CODE_NON_FUNGIBLE_TOKEN_INFO_V2) + .withVariants(Variant.V2, Variant.NFT) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public NftTokenInfoTranslator() { + public NftTokenInfoTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(NON_FUNGIBLE_TOKEN_INFO, NON_FUNGIBLE_TOKEN_INFO_V2); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); final var v2Enabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractTokenInfoV2Enabled(); - return attempt.isSelector(NON_FUNGIBLE_TOKEN_INFO) - || attempt.isSelectorIfConfigEnabled(v2Enabled, NON_FUNGIBLE_TOKEN_INFO_V2); + if (attempt.isMethod(NON_FUNGIBLE_TOKEN_INFO).isPresent()) return Optional.of(NON_FUNGIBLE_TOKEN_INFO); + if (attempt.isSelectorIfConfigEnabled(v2Enabled, NON_FUNGIBLE_TOKEN_INFO_V2)) + return Optional.of(NON_FUNGIBLE_TOKEN_INFO_V2); + return Optional.empty(); } /** @@ -64,9 +79,9 @@ public boolean matches(@NonNull final HtsCallAttempt attempt) { @Override public Call callFrom(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); - final var function = + final var method = attempt.isSelector(NON_FUNGIBLE_TOKEN_INFO) ? NON_FUNGIBLE_TOKEN_INFO : NON_FUNGIBLE_TOKEN_INFO_V2; - final var args = function.decodeCall(attempt.input().toArrayUnsafe()); + final var args = method.decodeCall(attempt.input().toArrayUnsafe()); final var token = attempt.linkedToken(fromHeadlongAddress(args.get(0))); return new NftTokenInfoCall( attempt.systemContractGasCalculator(), @@ -75,6 +90,6 @@ public Call callFrom(@NonNull final HtsCallAttempt attempt) { token, args.get(1), attempt.configuration(), - function); + method.function()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/ownerof/OwnerOfTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/ownerof/OwnerOfTranslator.java index 77e8cdd12f85..2a2f424c62d1 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/ownerof/OwnerOfTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/ownerof/OwnerOfTranslator.java @@ -17,12 +17,18 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ownerof; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asExactLongValueOrZero; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -32,22 +38,28 @@ @Singleton public class OwnerOfTranslator extends AbstractCallTranslator { /** Selector for ownerOf(uint256) method. */ - public static final Function OWNER_OF = new Function("ownerOf(uint256)", ReturnTypes.ADDRESS); + public static final SystemContractMethod OWNER_OF = SystemContractMethod.declare( + "ownerOf(uint256)", ReturnTypes.ADDRESS) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public OwnerOfTranslator() { + public OwnerOfTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(OWNER_OF); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(OWNER_OF); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(OWNER_OF); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/pauses/PausesTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/pauses/PausesTranslator.java index 165e4b39a359..ea5945cc18cc 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/pauses/PausesTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/pauses/PausesTranslator.java @@ -16,18 +16,24 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.pauses; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -38,9 +44,13 @@ @Singleton public class PausesTranslator extends AbstractCallTranslator { /** Selector for pauseToken(address) method. */ - public static final Function PAUSE = new Function("pauseToken(address)", ReturnTypes.INT_64); + public static final SystemContractMethod PAUSE = SystemContractMethod.declare( + "pauseToken(address)", ReturnTypes.INT_64) + .withCategories(Category.PAUSE_UNPAUSE); /** Selector for unpauseToken(address) method. */ - public static final Function UNPAUSE = new Function("unpauseToken(address)", ReturnTypes.INT_64); + public static final SystemContractMethod UNPAUSE = SystemContractMethod.declare( + "unpauseToken(address)", ReturnTypes.INT_64) + .withCategories(Category.PAUSE_UNPAUSE); private final PausesDecoder decoder; @@ -48,16 +58,20 @@ public class PausesTranslator extends AbstractCallTranslator { * @param decoder the decoder to use for pause calls */ @Inject - public PausesTranslator(@NonNull final PausesDecoder decoder) { + public PausesTranslator( + @NonNull final PausesDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(PAUSE, UNPAUSE); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(PAUSE, UNPAUSE); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(PAUSE, UNPAUSE); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslator.java index b21bdb77d5b4..7062e49cf614 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslator.java @@ -22,43 +22,70 @@ import com.hedera.node.app.service.contract.impl.exec.gas.DispatchGasCalculator; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class RejectTokensTranslator extends AbstractCallTranslator { - public static final Function TOKEN_REJECT = - new Function("rejectTokens(address,address[],(address,int64)[])", ReturnTypes.INT_64); - public static final Function HRC_TOKEN_REJECT_FT = new Function("rejectTokenFT()", ReturnTypes.INT_64); - public static final Function HRC_TOKEN_REJECT_NFT = new Function("rejectTokenNFTs(int64[])", ReturnTypes.INT_64); + public static final SystemContractMethod TOKEN_REJECT = SystemContractMethod.declare( + "rejectTokens(address,address[],(address,int64)[])", ReturnTypes.INT_64) + .withCategories(Category.REJECT); + public static final SystemContractMethod HRC_TOKEN_REJECT_FT = SystemContractMethod.declare( + "rejectTokenFT()", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.FT) + .withCategories(Category.REJECT); + public static final SystemContractMethod HRC_TOKEN_REJECT_NFT = SystemContractMethod.declare( + "rejectTokenNFTs(int64[])", ReturnTypes.INT_64) + .withVia(CallVia.PROXY) + .withVariant(Variant.NFT) + .withCategories(Category.REJECT); private final RejectTokensDecoder decoder; private final Map gasCalculators = new HashMap<>(); @Inject - public RejectTokensTranslator(@NonNull final RejectTokensDecoder decoder) { + public RejectTokensTranslator( + @NonNull final RejectTokensDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; - gasCalculators.put(TOKEN_REJECT, RejectTokensTranslator::gasRequirement); - gasCalculators.put(HRC_TOKEN_REJECT_FT, RejectTokensTranslator::gasRequirementHRCFungible); - gasCalculators.put(HRC_TOKEN_REJECT_NFT, RejectTokensTranslator::gasRequirementHRCNft); + + registerMethods(TOKEN_REJECT, HRC_TOKEN_REJECT_FT, HRC_TOKEN_REJECT_NFT); + + gasCalculators.put(TOKEN_REJECT.function(), RejectTokensTranslator::gasRequirement); + gasCalculators.put(HRC_TOKEN_REJECT_FT.function(), RejectTokensTranslator::gasRequirementHRCFungible); + gasCalculators.put(HRC_TOKEN_REJECT_NFT.function(), RejectTokensTranslator::gasRequirementHRCNft); } @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { final var rejectEnabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractRejectTokensEnabled(); + + if (!rejectEnabled) return Optional.empty(); return attempt.isTokenRedirect() - ? attempt.isSelectorIfConfigEnabled(rejectEnabled, HRC_TOKEN_REJECT_FT, HRC_TOKEN_REJECT_NFT) - : attempt.isSelectorIfConfigEnabled(rejectEnabled, TOKEN_REJECT); + ? attempt.isMethod(HRC_TOKEN_REJECT_FT, HRC_TOKEN_REJECT_NFT) + : attempt.isMethod(TOKEN_REJECT); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslator.java index 96e3fbb8ff7e..9beb8d2cd213 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslator.java @@ -16,32 +16,42 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.setapproval; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates setApprovalForAll (including ERC) call to the HTS system contract. There are no special cases for these * calls, so the returned {@link Call} is simply an instance of {@link DispatchForResponseCodeHtsCall}. */ +@Singleton public class SetApprovalForAllTranslator extends AbstractCallTranslator { /** Selector for setApprovalForAll(address,address,bool) method. */ - public static final Function SET_APPROVAL_FOR_ALL = - new Function("setApprovalForAll(address,address,bool)", ReturnTypes.INT); + public static final SystemContractMethod SET_APPROVAL_FOR_ALL = SystemContractMethod.declare( + "setApprovalForAll(address,address,bool)", ReturnTypes.INT) + .withCategory(Category.APPROVAL); /** Selector for setApprovalForAll(address,bool) method. */ - public static final Function ERC721_SET_APPROVAL_FOR_ALL = - new Function("setApprovalForAll(address,bool)", ReturnTypes.INT); + public static final SystemContractMethod ERC721_SET_APPROVAL_FOR_ALL = SystemContractMethod.declare( + "setApprovalForAll(address,bool)", ReturnTypes.INT) + .withVia(CallVia.PROXY) + .withCategories(Category.ERC721, Category.APPROVAL); private final SetApprovalForAllDecoder decoder; @@ -49,18 +59,21 @@ public class SetApprovalForAllTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { return attempt.isTokenRedirect() - ? attempt.isSelector(ERC721_SET_APPROVAL_FOR_ALL) - : attempt.isSelector(SET_APPROVAL_FOR_ALL); + ? attempt.isMethod(ERC721_SET_APPROVAL_FOR_ALL) + : attempt.isMethod(SET_APPROVAL_FOR_ALL); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/symbol/SymbolTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/symbol/SymbolTranslator.java index 90aacbd24666..c6c68d624044 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/symbol/SymbolTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/symbol/SymbolTranslator.java @@ -16,11 +16,18 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.symbol; -import com.esaulpaugh.headlong.abi.Function; +import static java.util.Objects.requireNonNull; + +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -30,22 +37,27 @@ @Singleton public class SymbolTranslator extends AbstractCallTranslator { /** Selector for symbol() method. */ - public static final Function SYMBOL = new Function("symbol()", ReturnTypes.STRING); + public static final SystemContractMethod SYMBOL = SystemContractMethod.declare("symbol()", ReturnTypes.STRING) + .withModifier(Modifier.VIEW) + .withCategories(Category.ERC20, Category.ERC721, Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public SymbolTranslator() { + public SymbolTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(SYMBOL); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(SYMBOL); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(SYMBOL); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslator.java index f92d1a31c4fc..35a833e0c9c5 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslator.java @@ -17,37 +17,50 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenexpiry; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenExpiry()} calls to the HTS system contract. */ +@Singleton public class TokenExpiryTranslator extends AbstractCallTranslator { /** Selector for getTokenExpiryInfo(address) method. */ - public static final Function TOKEN_EXPIRY = - new Function("getTokenExpiryInfo(address)", ReturnTypes.RESPONSE_CODE_EXPIRY); + public static final SystemContractMethod TOKEN_EXPIRY = SystemContractMethod.declare( + "getTokenExpiryInfo(address)", ReturnTypes.RESPONSE_CODE_EXPIRY) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TokenExpiryTranslator() { + public TokenExpiryTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_EXPIRY); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_EXPIRY); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(TOKEN_EXPIRY); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoCall.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoCall.java index 7a5f607ec273..4c82839e7cb9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoCall.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoCall.java @@ -83,7 +83,7 @@ public TokenInfoCall( return revertResult(status, gasRequirement); } - return function.getName().equals(TOKEN_INFO.getName()) + return function.getName().equals(TOKEN_INFO.methodName()) ? successResult( TOKEN_INFO .getOutputs() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslator.java index d65f7a9d0bc5..798896153c7f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslator.java @@ -19,43 +19,62 @@ import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenInfo()} calls to the HTS system contract. */ +@Singleton public class TokenInfoTranslator extends AbstractCallTranslator { /** Selector for getTokenInfo(address) method. */ - public static final Function TOKEN_INFO = - new Function("getTokenInfo(address)", ReturnTypes.RESPONSE_CODE_TOKEN_INFO); + public static final SystemContractMethod TOKEN_INFO = SystemContractMethod.declare( + "getTokenInfo(address)", ReturnTypes.RESPONSE_CODE_TOKEN_INFO) + .withModifier(Modifier.VIEW) + .withVariant(Variant.V1) + .withCategory(Category.TOKEN_QUERY); /** Selector for getTokenInfoV2(address) method. */ - public static final Function TOKEN_INFO_V2 = - new Function("getTokenInfoV2(address)", ReturnTypes.RESPONSE_CODE_TOKEN_INFO_V2); + public static final SystemContractMethod TOKEN_INFO_V2 = SystemContractMethod.declare( + "getTokenInfoV2(address)", ReturnTypes.RESPONSE_CODE_TOKEN_INFO_V2) + .withModifier(Modifier.VIEW) + .withVariant(Variant.V2) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TokenInfoTranslator() { + public TokenInfoTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_INFO, TOKEN_INFO_V2); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); + final var v2Enabled = attempt.configuration().getConfigData(ContractsConfig.class).systemContractTokenInfoV2Enabled(); - return attempt.isSelector(TOKEN_INFO) || attempt.isSelectorIfConfigEnabled(v2Enabled, TOKEN_INFO_V2); + if (attempt.isSelector(TOKEN_INFO)) return Optional.of(TOKEN_INFO); + if (attempt.isSelectorIfConfigEnabled(v2Enabled, TOKEN_INFO_V2)) return Optional.of(TOKEN_INFO_V2); + return Optional.empty(); } /** @@ -64,8 +83,8 @@ public boolean matches(@NonNull final HtsCallAttempt attempt) { @Override public Call callFrom(@NonNull final HtsCallAttempt attempt) { requireNonNull(attempt); - final var function = attempt.isSelector(TOKEN_INFO) ? TOKEN_INFO : TOKEN_INFO_V2; - final var args = function.decodeCall(attempt.input().toArrayUnsafe()); + final var method = attempt.isSelector(TOKEN_INFO) ? TOKEN_INFO : TOKEN_INFO_V2; + final var args = method.decodeCall(attempt.input().toArrayUnsafe()); final var token = attempt.linkedToken(fromHeadlongAddress(args.get(0))); return new TokenInfoCall( attempt.systemContractGasCalculator(), @@ -73,6 +92,6 @@ public Call callFrom(@NonNull final HtsCallAttempt attempt) { attempt.isStaticCall(), token, attempt.configuration(), - function); + method.function()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenkey/TokenKeyTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenkey/TokenKeyTranslator.java index 0565b69dd5dc..f21cd4993cc4 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenkey/TokenKeyTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenkey/TokenKeyTranslator.java @@ -17,42 +17,55 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenkey; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.hapi.utils.InvalidTransactionException; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; import java.math.BigInteger; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenKey()} calls to the HTS system contract. */ +@Singleton public class TokenKeyTranslator extends AbstractCallTranslator { /** Selector for getTokenKey(address,uint) method. */ - public static final Function TOKEN_KEY = - new Function("getTokenKey(address,uint)", ReturnTypes.RESPONSE_CODE_TOKEN_KEY); + public static final SystemContractMethod TOKEN_KEY = SystemContractMethod.declare( + "getTokenKey(address,uint)", ReturnTypes.RESPONSE_CODE_TOKEN_KEY) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TokenKeyTranslator() { + public TokenKeyTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_KEY); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_KEY); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(TOKEN_KEY); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokentype/TokenTypeTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokentype/TokenTypeTranslator.java index fed5aa7aef00..83477aa72cf4 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokentype/TokenTypeTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokentype/TokenTypeTranslator.java @@ -17,36 +17,50 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokentype; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates {@code getTokenType()} calls to the HTS system contract. */ +@Singleton public class TokenTypeTranslator extends AbstractCallTranslator { /** Selector for getTokenType(address) method. */ - public static final Function TOKEN_TYPE = new Function("getTokenType(address)", ReturnTypes.RESPONSE_CODE_INT32); + public static final SystemContractMethod TOKEN_TYPE = SystemContractMethod.declare( + "getTokenType(address)", ReturnTypes.RESPONSE_CODE_INT32) + .withModifier(Modifier.VIEW) + .withCategory(Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TokenTypeTranslator() { + public TokenTypeTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_TYPE); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_TYPE); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(TOKEN_TYPE); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenuri/TokenUriTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenuri/TokenUriTranslator.java index 425753d7bbb2..c0c6e1a03ef7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenuri/TokenUriTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/tokenuri/TokenUriTranslator.java @@ -17,13 +17,19 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenuri; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asExactLongValueOrZero; +import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,22 +39,28 @@ @Singleton public class TokenUriTranslator extends AbstractCallTranslator { /** Selector for tokenURI(uint256) method. */ - public static final Function TOKEN_URI = new Function("tokenURI(uint256)", ReturnTypes.STRING); + public static final SystemContractMethod TOKEN_URI = SystemContractMethod.declare( + "tokenURI(uint256)", ReturnTypes.STRING) + .withModifier(Modifier.VIEW) + .withCategories(Category.ERC721, Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TokenUriTranslator() { + public TokenUriTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOKEN_URI); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_URI); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + requireNonNull(attempt); + return attempt.isMethod(TOKEN_URI); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/totalsupply/TotalSupplyTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/totalsupply/TotalSupplyTranslator.java index fc30f4754d08..476c9bcac1f0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/totalsupply/TotalSupplyTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/totalsupply/TotalSupplyTranslator.java @@ -16,11 +16,16 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.totalsupply; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Modifier; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -30,22 +35,27 @@ @Singleton public class TotalSupplyTranslator extends AbstractCallTranslator { /** Selector for totalSupply() method. */ - public static final Function TOTAL_SUPPLY = new Function("totalSupply()", ReturnTypes.INT); + public static final SystemContractMethod TOTAL_SUPPLY = SystemContractMethod.declare( + "totalSupply()", ReturnTypes.INT) + .withModifier(Modifier.VIEW) + .withCategories(Category.ERC20, Category.ERC721, Category.TOKEN_QUERY); /** * Default constructor for injection. */ @Inject - public TotalSupplyTranslator() { + public TotalSupplyTranslator( + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { // Dagger2 + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods(TOTAL_SUPPLY); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TOTAL_SUPPLY); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + return attempt.isMethod(TOTAL_SUPPLY); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersTranslator.java index bfee6100667c..9c786bf48f90 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/ClassicTransfersTranslator.java @@ -21,13 +21,18 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.SpecialRewardReceivers.SPECIAL_REWARD_RECEIVERS; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.SystemAccountCreditScreen.SYSTEM_ACCOUNT_CREDIT_SCREEN; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -39,44 +44,59 @@ public class ClassicTransfersTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + if (attempt.isTokenRedirect()) return Optional.empty(); + return attempt.isMethod( + CRYPTO_TRANSFER, + CRYPTO_TRANSFER_V2, + TRANSFER_TOKENS, + TRANSFER_TOKEN, + TRANSFER_NFTS, + TRANSFER_NFT, + TRANSFER_FROM, + TRANSFER_NFT_FROM); } @Override @@ -143,11 +182,18 @@ public ClassicTransfersCall callFrom(@NonNull final HtsCallAttempt attempt) { } private boolean isClassicCall(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector( - CRYPTO_TRANSFER, CRYPTO_TRANSFER_V2, TRANSFER_TOKENS, TRANSFER_TOKEN, TRANSFER_NFTS, TRANSFER_NFT); + return attempt.isMethod( + CRYPTO_TRANSFER, + CRYPTO_TRANSFER_V2, + TRANSFER_TOKENS, + TRANSFER_TOKEN, + TRANSFER_NFTS, + TRANSFER_NFT) + .isPresent(); } private boolean isClassicCallSupportingQualifiedDelegate(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(TRANSFER_TOKENS, TRANSFER_TOKEN, TRANSFER_NFTS, TRANSFER_NFT); + return attempt.isMethod(TRANSFER_TOKENS, TRANSFER_TOKEN, TRANSFER_NFTS, TRANSFER_NFT) + .isPresent(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java index f956029043b7..de7195586225 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc20TransfersTranslator.java @@ -21,14 +21,19 @@ import static java.util.Objects.requireNonNull; import com.esaulpaugh.headlong.abi.Address; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.math.BigInteger; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -40,27 +45,39 @@ public class Erc20TransfersTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + // Here, for ERC-20 == fungible tokens, we allow `transferFrom` (signature shared by ERC-20 + // and ERC-721) even if the token type doesn't exist. (This is the case when `redirectTokenType()` + // returns `null`.) + if (!attempt.isTokenRedirect()) return Optional.empty(); + if (attempt.redirectTokenType() == NON_FUNGIBLE_UNIQUE) return Optional.empty(); + return attempt.isMethod(ERC_20_TRANSFER, ERC_20_TRANSFER_FROM); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc721TransferFromTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc721TransferFromTranslator.java index 21173a4185c2..8599909179ac 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc721TransferFromTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/transfer/Erc721TransferFromTranslator.java @@ -20,12 +20,17 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.SpecialRewardReceivers.SPECIAL_REWARD_RECEIVERS; import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import edu.umd.cs.findbugs.annotations.NonNull; import java.math.BigInteger; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -38,22 +43,30 @@ public class Erc721TransferFromTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + // Here, for ERC-721 == non-fungible tokens, the token type must exist + if (!attempt.isTokenRedirect()) return Optional.empty(); + if (attempt.redirectTokenType() != NON_FUNGIBLE_UNIQUE) return Optional.empty(); + return attempt.isMethod(ERC_721_TRANSFER_FROM); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateExpiryTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateExpiryTranslator.java index 1d91cf22dce1..a373c0ddf6ac 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateExpiryTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateExpiryTranslator.java @@ -20,35 +20,46 @@ import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.EXPIRY_V2; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder.FAILURE_CUSTOMIZER; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Arrays; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; /** * Translates ERC-721 {@code updateTokenExpiryInfo()} calls to the HTS system contract. */ +@Singleton public class UpdateExpiryTranslator extends AbstractCallTranslator { /** * Selector for updateTokenExpiryInfo(address, EXPIRY) method. */ - public static final Function UPDATE_TOKEN_EXPIRY_INFO_V1 = - new Function("updateTokenExpiryInfo(address," + EXPIRY + ")", ReturnTypes.INT); + public static final SystemContractMethod UPDATE_TOKEN_EXPIRY_INFO_V1 = SystemContractMethod.declare( + "updateTokenExpiryInfo(address," + EXPIRY + ")", ReturnTypes.INT) + .withVariant(Variant.V1) + .withCategories(Category.UPDATE); /** * Selector for updateTokenExpiryInfo(address, EXPIRY_V2) method. */ - public static final Function UPDATE_TOKEN_EXPIRY_INFO_V2 = - new Function("updateTokenExpiryInfo(address," + EXPIRY_V2 + ")", ReturnTypes.INT); + public static final SystemContractMethod UPDATE_TOKEN_EXPIRY_INFO_V2 = SystemContractMethod.declare( + "updateTokenExpiryInfo(address," + EXPIRY_V2 + ")", ReturnTypes.INT) + .withVariant(Variant.V2) + .withCategories(Category.UPDATE); private final UpdateDecoder decoder; @@ -56,13 +67,19 @@ public class UpdateExpiryTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + return attempt.isMethod(UPDATE_TOKEN_EXPIRY_INFO_V1, UPDATE_TOKEN_EXPIRY_INFO_V2); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateKeysTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateKeysTranslator.java index 3076a6a433d8..97bfcd81d95f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateKeysTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateKeysTranslator.java @@ -20,24 +20,31 @@ import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.TOKEN_KEY; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder.FAILURE_CUSTOMIZER; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class UpdateKeysTranslator extends AbstractCallTranslator { /** Selector for updateTokenKeys(address, TOKEN_KEY[]) method. */ - public static final Function TOKEN_UPDATE_KEYS_FUNCTION = - new Function("updateTokenKeys(address," + TOKEN_KEY + ARRAY_BRACKETS + ")", ReturnTypes.INT); + public static final SystemContractMethod TOKEN_UPDATE_KEYS_FUNCTION = SystemContractMethod.declare( + "updateTokenKeys(address," + TOKEN_KEY + ARRAY_BRACKETS + ")", ReturnTypes.INT) + .withCategories(Category.UPDATE); private final UpdateDecoder decoder; @@ -45,13 +52,19 @@ public class UpdateKeysTranslator extends AbstractCallTranslator * @param decoder the decoder to use for token update keys calls */ @Inject - public UpdateKeysTranslator(UpdateDecoder decoder) { + public UpdateKeysTranslator( + @NonNull final UpdateDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(TOKEN_UPDATE_KEYS_FUNCTION); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { - return attempt.isSelector(TOKEN_UPDATE_KEYS_FUNCTION); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + return attempt.isMethod(TOKEN_UPDATE_KEYS_FUNCTION); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslator.java index ada69222db8d..4ff8440fa90e 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslator.java @@ -16,25 +16,34 @@ package com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class UpdateNFTsMetadataTranslator extends AbstractCallTranslator { /** Selector for updateNFTsMetadata(address,int64[],bytes) method. */ - public static final Function UPDATE_NFTs_METADATA = - new Function("updateNFTsMetadata(address,int64[],bytes)", ReturnTypes.INT); + public static final SystemContractMethod UPDATE_NFTs_METADATA = SystemContractMethod.declare( + "updateNFTsMetadata(address,int64[],bytes)", ReturnTypes.INT) + .withVariants(Variant.NFT, Variant.WITH_METADATA) + .withCategories(Category.UPDATE); private final UpdateDecoder decoder; @@ -42,14 +51,21 @@ public class UpdateNFTsMetadataTranslator extends AbstractCallTranslator identifyMethod(@NonNull final HtsCallAttempt attempt) { + if (!attempt.configuration().getConfigData(ContractsConfig.class).systemContractUpdateNFTsMetadataEnabled()) + return Optional.empty(); + return attempt.isMethod(UPDATE_NFTs_METADATA); } @Override diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateTranslator.java index 5d336bbe8ae9..b95b386f4fe1 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/update/UpdateTranslator.java @@ -22,23 +22,30 @@ import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.HEDERA_TOKEN_WITH_METADATA; import static com.hedera.node.app.hapi.utils.contracts.ParsingConstants.TOKEN_KEY; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class UpdateTranslator extends AbstractCallTranslator { private static final String UPDATE_TOKEN_INFO_STRING = "updateTokenInfo(address,"; private static final String HEDERA_TOKEN_STRUCT = @@ -48,40 +55,58 @@ public class UpdateTranslator extends AbstractCallTranslator { private static final String HEDERA_TOKEN_STRUCT_V3 = "(string,string,address,string,bool,int64,bool," + TOKEN_KEY + ARRAY_BRACKETS + "," + EXPIRY_V2 + ")"; /** Selector for updateTokenInfo(address, HEDERA_TOKEN_STRUCT) method. */ - public static final Function TOKEN_UPDATE_INFO_FUNCTION_V1 = - new Function(UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT + ")", ReturnTypes.INT); + public static final SystemContractMethod TOKEN_UPDATE_INFO_FUNCTION_V1 = SystemContractMethod.declare( + UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT + ")", ReturnTypes.INT) + .withVariant(Variant.V1) + .withCategories(Category.UPDATE); /** Selector for updateTokenInfo(address, HEDERA_TOKEN_STRUCT_V2) method. */ - public static final Function TOKEN_UPDATE_INFO_FUNCTION_V2 = - new Function(UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT_V2 + ")", ReturnTypes.INT); + public static final SystemContractMethod TOKEN_UPDATE_INFO_FUNCTION_V2 = SystemContractMethod.declare( + UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT_V2 + ")", ReturnTypes.INT) + .withVariant(Variant.V2) + .withCategories(Category.UPDATE); /** Selector for updateTokenInfo(address, HEDERA_TOKEN_STRUCT_V3) method. */ - public static final Function TOKEN_UPDATE_INFO_FUNCTION_V3 = - new Function(UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT_V3 + ")", ReturnTypes.INT); + public static final SystemContractMethod TOKEN_UPDATE_INFO_FUNCTION_V3 = SystemContractMethod.declare( + UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_STRUCT_V3 + ")", ReturnTypes.INT) + .withVariant(Variant.V3) + .withCategories(Category.UPDATE); /** Selector for updateTokenInfo(address, HEDERA_TOKEN_WITH_METADATA) method. */ - public static final Function TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA = - new Function(UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_WITH_METADATA + ")", ReturnTypes.INT); + public static final SystemContractMethod TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA = SystemContractMethod.declare( + UPDATE_TOKEN_INFO_STRING + HEDERA_TOKEN_WITH_METADATA + ")", ReturnTypes.INT) + .withVariant(Variant.WITH_METADATA) + .withCategories(Category.UPDATE); - private static final Map updateSelectorsMap = new HashMap<>(); + private static final Map updateMethodsMap = new HashMap<>(); /** * @param decoder the decoder to use for token update info calls */ @Inject - public UpdateTranslator(final UpdateDecoder decoder) { - updateSelectorsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V1, decoder::decodeTokenUpdateV1); - updateSelectorsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V2, decoder::decodeTokenUpdateV2); - updateSelectorsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V3, decoder::decodeTokenUpdateV3); - updateSelectorsMap.put(TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA, decoder::decodeTokenUpdateWithMetadata); + public UpdateTranslator( + final UpdateDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + + registerMethods( + TOKEN_UPDATE_INFO_FUNCTION_V1, + TOKEN_UPDATE_INFO_FUNCTION_V2, + TOKEN_UPDATE_INFO_FUNCTION_V3, + TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA); + + updateMethodsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V1, decoder::decodeTokenUpdateV1); + updateMethodsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V2, decoder::decodeTokenUpdateV2); + updateMethodsMap.put(TOKEN_UPDATE_INFO_FUNCTION_V3, decoder::decodeTokenUpdateV3); + updateMethodsMap.put(TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA, decoder::decodeTokenUpdateWithMetadata); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { final boolean metadataSupport = attempt.configuration().getConfigData(ContractsConfig.class).metadataKeyAndFieldEnabled(); - return updateSelectorsMap.keySet().stream() - .anyMatch(selector -> selector.equals(TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA) - ? attempt.isSelectorIfConfigEnabled(metadataSupport, selector) - : attempt.isSelector(selector)); + if (attempt.isSelectorIfConfigEnabled(metadataSupport, TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA)) + return Optional.of(TOKEN_UPDATE_INFO_FUNCTION_WITH_METADATA); + return updateMethodsMap.keySet().stream().filter(attempt::isSelector).findFirst(); } @Override @@ -106,7 +131,7 @@ public static long gasRequirement( } private TransactionBody nominalBodyFor(@NonNull final HtsCallAttempt attempt) { - return updateSelectorsMap.entrySet().stream() + return updateMethodsMap.entrySet().stream() .filter(entry -> attempt.isSelector(entry.getKey())) .map(entry -> entry.getValue().decode(attempt)) .findFirst() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslator.java index 75788816cfd1..e365d029a0c4 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslator.java @@ -20,44 +20,63 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.updatetokencustomfees.UpdateTokenCustomFeesDecoder.UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_STRING; import static java.util.Objects.requireNonNull; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Arrays; +import java.util.Optional; import javax.inject.Inject; +import javax.inject.Singleton; +@Singleton public class UpdateTokenCustomFeesTranslator extends AbstractCallTranslator { /** Selector for updateFungibleTokenCustomFees(address,(int64,address,bool,bool,address)[],(int64,int64,int64,int64,bool,address)[]) method. */ - public static final Function UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION = - new Function(UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_STRING, ReturnTypes.INT); + public static final SystemContractMethod UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION = SystemContractMethod.declare( + UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_STRING, ReturnTypes.INT) + .withVariants(Variant.FT, Variant.WITH_CUSTOM_FEES) + .withCategories(Category.UPDATE); /** Selector for updateNonFungibleTokenCustomFees(address,(int64,address,bool,bool,address)[],(int64,int64,int64,address,bool,address)[]) method. */ - public static final Function UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION = - new Function(UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_STRING, ReturnTypes.INT); + public static final SystemContractMethod UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION = + SystemContractMethod.declare(UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_STRING, ReturnTypes.INT) + .withVariants(Variant.NFT, Variant.WITH_CUSTOM_FEES) + .withCategories(Category.UPDATE); private final UpdateTokenCustomFeesDecoder decoder; @Inject - public UpdateTokenCustomFeesTranslator(@NonNull final UpdateTokenCustomFeesDecoder decoder) { + public UpdateTokenCustomFeesTranslator( + @NonNull final UpdateTokenCustomFeesDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); + requireNonNull(decoder); this.decoder = decoder; + + registerMethods(UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION, UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION); } @Override - public boolean matches(@NonNull HtsCallAttempt attempt) { - return attempt.configuration().getConfigData(ContractsConfig.class).systemContractUpdateCustomFeesEnabled() - && attempt.isSelector( - UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION, UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + if (!attempt.configuration().getConfigData(ContractsConfig.class).systemContractUpdateCustomFeesEnabled()) + return Optional.empty(); + return attempt.isMethod( + UPDATE_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION, UPDATE_NON_FUNGIBLE_TOKEN_CUSTOM_FEES_FUNCTION); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/wipe/WipeTranslator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/wipe/WipeTranslator.java index 9d7e43bfecc3..38281a0a0a63 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/wipe/WipeTranslator.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/systemcontracts/hts/wipe/WipeTranslator.java @@ -18,18 +18,23 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall.FailureCustomizer.NOOP_CUSTOMIZER; -import com.esaulpaugh.headlong.abi.Function; import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.AbstractCallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Category; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -37,28 +42,37 @@ public class WipeTranslator extends AbstractCallTranslator { /** Selector for wipeTokenAccount(address,address,uint32) method. */ - public static final Function WIPE_FUNGIBLE_V1 = - new Function("wipeTokenAccount(address,address,uint32)", ReturnTypes.INT); + public static final SystemContractMethod WIPE_FUNGIBLE_V1 = SystemContractMethod.declare( + "wipeTokenAccount(address,address,uint32)", ReturnTypes.INT) + .withVariants(Variant.V1, Variant.FT) + .withCategories(Category.WIPE); /** Selector for wipeTokenAccount(address,address,int64) method. */ - public static final Function WIPE_FUNGIBLE_V2 = - new Function("wipeTokenAccount(address,address,int64)", ReturnTypes.INT); + public static final SystemContractMethod WIPE_FUNGIBLE_V2 = SystemContractMethod.declare( + "wipeTokenAccount(address,address,int64)", ReturnTypes.INT) + .withVariants(Variant.V2, Variant.FT) + .withCategories(Category.WIPE); /** Selector for wipeTokenAccountNFT(address,address,int64[]) method. */ - public static final Function WIPE_NFT = - new Function("wipeTokenAccountNFT(address,address,int64[])", ReturnTypes.INT); + public static final SystemContractMethod WIPE_NFT = SystemContractMethod.declare( + "wipeTokenAccountNFT(address,address,int64[])", ReturnTypes.INT) + .withVariant(Variant.NFT) + .withCategories(Category.WIPE); private final WipeDecoder decoder; @Inject - public WipeTranslator(@NonNull final WipeDecoder decoder) { + public WipeTranslator( + @NonNull final WipeDecoder decoder, + @NonNull final SystemContractMethodRegistry systemContractMethodRegistry, + @NonNull final ContractMetrics contractMetrics) { + super(SystemContractMethod.SystemContract.HTS, systemContractMethodRegistry, contractMetrics); this.decoder = decoder; + + registerMethods(WIPE_FUNGIBLE_V1, WIPE_FUNGIBLE_V2, WIPE_NFT); } - /** - * {@inheritDoc} - */ @Override - public boolean matches(@NonNull final HtsCallAttempt attempt) { - return attempt.isSelector(WIPE_FUNGIBLE_V1, WIPE_FUNGIBLE_V2, WIPE_NFT); + public @NonNull Optional identifyMethod(@NonNull final HtsCallAttempt attempt) { + return attempt.isMethod(WIPE_FUNGIBLE_V1, WIPE_FUNGIBLE_V2, WIPE_NFT); } /** diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethod.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethod.java new file mode 100644 index 000000000000..abfa3a9331b6 --- /dev/null +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethod.java @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2024 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.contract.impl.exec.utils; + +import static java.util.Objects.requireNonNull; + +import com.esaulpaugh.headlong.abi.Function; +import com.esaulpaugh.headlong.abi.Tuple; +import com.esaulpaugh.headlong.abi.TupleType; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.tuweni.bytes.Bytes; + +/** + * Represents a system contract method: It's signature + outputs, and other information about how it is declared + * @param function A headlong description of this method: signature + outputs, selector + * @param systemContract Which system contract this method is part of (HAS, HSS, HTS, PRNG, EXCHANGE) + * @param via Whether called directly or via redirect (aka proxy) + * @param categories Set of category flags possibly empty + * @param modifier An optional Solidity function modifier (e.g., pure or view) + * @param variants Set of method variants (e.g., version number, or FT vs NFT), possibly empty + */ +public record SystemContractMethod( + @NonNull Function function, + @NonNull Optional systemContract, + @NonNull CallVia via, + @NonNull EnumSet categories, + @NonNull Optional modifier, + @NonNull EnumSet variants) { + + public SystemContractMethod { + requireNonNull(function); + requireNonNull(systemContract); + requireNonNull(via); + requireNonNull(categories); + requireNonNull(modifier); + requireNonNull(variants); + } + + /** + * Factory to create a SystemContractMethod given its signature and outputs + * + * This SystemContractMethod is incomplete in that it doesn't have the SystemContract field, + * which must be added later (with `withContract`) + */ + public static SystemContractMethod declare(@NonNull final String signature, @NonNull final String outputs) { + final var function = new com.esaulpaugh.headlong.abi.Function(signature, outputs); + return new SystemContractMethod( + function, + Optional.empty(), + CallVia.DIRECT, + EnumSet.noneOf(Category.class), + Optional.empty(), + EnumSet.noneOf(Variant.class)); + } + + /** + * Factory to create a SystemContractMethod given its signature when it returns nothing + * + * This SystemContractMethod is incomplete in that it doesn't have the SystemContract field, + * which must be added later (with `withContract`) + */ + public static SystemContractMethod declare(@NonNull final String signature) { + final var function = new com.esaulpaugh.headlong.abi.Function(signature); + return new SystemContractMethod( + function, + Optional.empty(), + CallVia.DIRECT, + EnumSet.noneOf(Category.class), + Optional.empty(), + EnumSet.noneOf(Variant.class)); + } + + /** + * Verify that the SystemContractMethod was created correctly + * + * Specifically, check that a SystemContract was provided for it eventually + */ + public void verifyComplete() { + if (systemContract.isEmpty()) { + throw new IllegalStateException("System contract %s is empty".formatted(function.getName())); + } + } + + /** The system contract "kind" for this SystemContractMethod */ + public enum SystemContract { + HTS, + HAS, + HSS, + PNRG, + EXCHANGE + } + + public interface AsSuffix { + @NonNull + String asSuffix(); + } + + /** Says that this SystemContractMethod is called directly or via redirect/proxy */ + public enum CallVia implements AsSuffix { + DIRECT(""), + PROXY("[PROXY]"); + + private final String asSuffix; + + CallVia(@NonNull final String viaSuffix) { + asSuffix = viaSuffix; + } + + public @NonNull String asSuffix() { + return asSuffix; + } + } + + /** + * Says that this SystemContractMethod is a view function or a pure function (as in Solidity). + * + * If neither is specified then it is a normal (state-changing) function. + */ + public enum Modifier implements AsSuffix { + VIEW("VIEW"), + PURE("PURE"); + + private final String asSuffix; + + Modifier(String modifierSuffix) { + this.asSuffix = modifierSuffix; + } + + public @NonNull String asSuffix() { + return asSuffix; + } + } + + /** + * Categorizes the SystemContractMethod. None, one, or more of these categories can be specified. + * + * Useful for grouping methods together. + */ + public enum Category implements AsSuffix { + ERC20("ERC20", "(can overlap with ERC721)"), + ERC721("ERC721", "(can overlap with ERC20)"), + + SCHEDULE("SCHEDULE"), + TOKEN_QUERY("TOKEN_QUERY"), + + ALIASES("ALIASES"), + IS_AUTHORIZED("IS_AUTHORIZED"), + + AIRDROP("AIRDROP"), + ALLOWANCE("ALLOWANCE"), + APPROVAL("APPROVAL"), + ASSOCIATION("ASSOCIATION"), + CREATE_DELETE_TOKEN("CREATE_OR_DELETE_TOKEN", "(Create or Delete Token)"), + FREEZE_UNFREEZE("FREEZE_UNFREEZE", "(Freeze or Unfreeze Token)"), + KYC("KYC"), + MINT_BURN("MINT_OR_BURN", "(Mint or Burn Token)"), + PAUSE_UNPAUSE("PAUSE_UNPAUSE", "(Pause or Unpause Token)"), + REJECT("REJECT_TOKEN"), + TRANSFER("TRANSFER_TOKEN"), + UPDATE("UPDATE_TOKEN"), + WIPE("WIPE_TOKEN"); + + private final String asSuffix; + private final String clarification; + + Category(@NonNull final String categorySuffix) { + this.asSuffix = requireNonNull(categorySuffix); + this.clarification = this.asSuffix; + } + + Category(@NonNull final String categorySuffix, @NonNull final String clarification) { + this.asSuffix = requireNonNull(categorySuffix); + this.clarification = requireNonNull(clarification); + } + + public @NonNull String asSuffix() { + return asSuffix; + } + + public @NonNull String clarification() { + return clarification; + } + } + + /** + * Distinguishes overloads of SystemContractMethods that have the same simple name. + */ + public enum Variant implements AsSuffix { + FT, + NFT, + V1, + V2, + V3, + WITH_METADATA, + WITH_CUSTOM_FEES; + + public @NonNull String asSuffix() { + return name(); + } + } + + // Fluent builders + + public @NonNull SystemContractMethod withContract(@NonNull final SystemContract systemContract) { + return new SystemContractMethod(function, Optional.of(systemContract), via, categories, modifier, variants); + } + + public @NonNull SystemContractMethod withVia(@NonNull final CallVia via) { + return new SystemContractMethod(function, systemContract, via, categories, modifier, variants); + } + + public @NonNull SystemContractMethod withCategories(@NonNull final Category... categories) { + final var c = EnumSet.copyOf(this.categories); + c.addAll(Arrays.asList(categories)); + return new SystemContractMethod(function, systemContract, via, c, modifier, variants); + } + + public @NonNull SystemContractMethod withCategory(@NonNull final Category category) { + final var c = EnumSet.copyOf(categories); + c.add(category); + return new SystemContractMethod(function, systemContract, via, c, modifier, variants); + } + + public @NonNull SystemContractMethod withModifier(@NonNull final Modifier modifier) { + return new SystemContractMethod(function, systemContract, via, categories, Optional.of(modifier), variants); + } + + public @NonNull SystemContractMethod withVariants(@NonNull final Variant... variants) { + final var v = EnumSet.copyOf(this.variants); + v.addAll(Arrays.asList(variants)); + return new SystemContractMethod(function, systemContract, via, categories, modifier, v); + } + + public @NonNull SystemContractMethod withVariant(@NonNull final Variant variant) { + final var v = EnumSet.copyOf(variants); + v.add(variant); + return new SystemContractMethod(function, systemContract, via, categories, modifier, v); + } + + // Forwarding to com.esaulpaugh.headlong.abi.Function + + public Tuple decodeCall(byte[] call) { + return function.decodeCall(call); + } + + public ByteBuffer encodeCall(Tuple tuple) { + return function.encodeCall(tuple); + } + + public ByteBuffer encodeCallWithArgs(Object... args) { + return function.encodeCallWithArgs(args); + } + + public TupleType getOutputs() { + return function.getOutputs(); + } + + public @NonNull String signature() { + return function.getCanonicalSignature(); + } + + public @NonNull String signatureWithReturn() { + return signature() + ':' + function.getOutputs(); + } + + public @NonNull byte[] selector() { + return function.selector(); + } + + public long selectorLong() { + return Bytes.wrap(function.selector()).toLong(ByteOrder.BIG_ENDIAN); + } + + public @NonNull String selectorHex() { + return function.selectorHex(); + } + + public boolean hasVariant(@NonNull final Variant variant) { + return variants.contains(variant); + } + + /** + * Return the method's name (simple, undecorated) + * @return the method's name + */ + public @NonNull String methodName() { + return function.getName(); + } + + /** + * Return the method's name with variant decorations + * + * The variant decorations (e.g., `_V1` and `_V2`) distinguish overloads of the method + * @return the method names with the variants as suffix + */ + public @NonNull String variatedMethodName() { + return methodName() + variantsSuffix(); + } + + public @NonNull String fullyDecoratedMethodName() { + var name = qualifiedMethodName(); + name += modifiersSuffix(); + name += categoriesSuffix(); + return name; + } + + /** + * "Qualified" method name has the contract name in front of it, and the variants appended to it. + */ + public @NonNull String qualifiedMethodName() { + final var systemContractName = systemContract.map(Enum::name).orElse("???"); + final var methodName = + switch (via) { + case DIRECT -> systemContractName + "." + variatedMethodName(); + case PROXY -> systemContractName + "(PROXY)." + variatedMethodName(); + }; + return methodName; + } + + private @NonNull String variantsSuffix() { + if (variants.isEmpty()) return ""; + return variants.stream().map(Variant::asSuffix).sorted().collect(Collectors.joining("_", "_", "")); + } + + private @NonNull String categoriesSuffix() { + if (categories.isEmpty()) return ""; + return categories.stream().map(Category::asSuffix).sorted().collect(Collectors.joining(",", "_[", "]")); + } + + private @NonNull String modifiersSuffix() { + if (modifier.isEmpty()) return ""; + return "_[" + modifier.get().asSuffix() + "]"; + } +} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethodRegistry.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethodRegistry.java new file mode 100644 index 000000000000..9778fab3ce92 --- /dev/null +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/SystemContractMethodRegistry.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024 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.contract.impl.exec.utils; + +import static java.util.Comparator.comparing; +import static java.util.Objects.requireNonNull; + +import com.google.common.annotations.VisibleForTesting; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Collection; +import java.util.SequencedCollection; +import java.util.concurrent.ConcurrentHashMap; +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * A registry for all the system contract methods - their names, selectors, and signatures. + * + * Methods are added to this registry when they're defined in the various `FooTranslator` classes, + * which, since they're all (or should be) Dagger singletons, is done as the smart contract service + * is coming up. Thus, the completed registry is available once processing starts, and so is ready + * for use to enumerate all system contract methods. + * + * The principal use case for this registry is to be able to generate various per-system-contract-method + * metrics. + */ +@Singleton +public class SystemContractMethodRegistry { + + private static final int EXPECTED_SYSTEM_CONTRACT_METHODS_UPPER_BOUND = 250; + private final ConcurrentHashMap byName = + new ConcurrentHashMap<>(EXPECTED_SYSTEM_CONTRACT_METHODS_UPPER_BOUND); + + @Inject + public SystemContractMethodRegistry() { + requireNonNull(SystemContractMethod.SystemContract.HTS); // DEBUGGING + } + + /** + * Add a system contract method into the registry of system contract methods + */ + public void register(@NonNull final SystemContractMethod systemContractMethod) { + requireNonNull(systemContractMethod); + + var keyName = systemContractMethod.variatedMethodName(); + if (systemContractMethod.via() == CallVia.PROXY) + keyName += systemContractMethod.via().asSuffix(); + + byName.putIfAbsent(keyName, systemContractMethod); + } + + // Queries: + + public long size() { + return byName.size(); + } + + public @NonNull SequencedCollection allQualifiedMethods() { + return allMethodsGivenMapper(SystemContractMethod::qualifiedMethodName); + } + + public @NonNull SequencedCollection allSignatures() { + return allMethodsGivenMapper(SystemContractMethod::signature); + } + + public @NonNull SequencedCollection allSignaturesWithReturns() { + return allMethodsGivenMapper(SystemContractMethod::signatureWithReturn); + } + + public @NonNull SequencedCollection allMethodsGivenMapper( + @NonNull final java.util.function.Function methodMapper) { + return byName.values().stream().map(methodMapper).sorted().toList(); + } + + public @NonNull Collection allMethods() { + return byName.values(); + } + + @VisibleForTesting + public @NonNull String allMethodsAsTable() { + final var allMethods = allMethods().stream() + .sorted(comparing(SystemContractMethod::qualifiedMethodName)) + .toList(); + final var sb = new StringBuilder(); + for (final var method : allMethods) { + sb.append("%s: 0x%s - %s\n" + .formatted(method.qualifiedMethodName(), method.selectorHex(), method.signatureWithReturn())); + } + return sb.toString(); + } +} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/AbstractContractTransactionHandler.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/AbstractContractTransactionHandler.java index f2ab8b4aeb79..1e6b2f5afeb9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/AbstractContractTransactionHandler.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/AbstractContractTransactionHandler.java @@ -104,4 +104,9 @@ protected void bumpExceptionMetrics(@NonNull final HederaFunctionality functiona @NonNull final SigValueObj sigValObj) { throw new IllegalStateException("must be overridden if `calculateFees` _not_ overridden"); } + + protected @NonNull TransactionComponent getTransactionComponent( + @NonNull final HandleContext context, @NonNull final HederaFunctionality functionality) { + return provider.get().create(context, functionality); + } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallHandler.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallHandler.java index 33eaf3c5a5c8..fbd0ecd4d541 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallHandler.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallHandler.java @@ -65,7 +65,7 @@ public ContractCallHandler( @Override public void handle(@NonNull final HandleContext context) throws HandleException { // Create the transaction-scoped component - final var component = provider.get().create(context, CONTRACT_CALL); + final var component = getTransactionComponent(context, CONTRACT_CALL); // Run its in-scope transaction and get the outcome final var outcome = component.contextTransactionProcessor().call(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallLocalHandler.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallLocalHandler.java index 4c08ffcfedfd..53fcdc969619 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallLocalHandler.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCallLocalHandler.java @@ -39,6 +39,7 @@ import com.hedera.hapi.node.transaction.Response; import com.hedera.node.app.hapi.utils.CommonPbjConverters; import com.hedera.node.app.hapi.utils.fee.SmartContractFeeBuilder; +import com.hedera.node.app.service.contract.impl.ContractServiceComponent; import com.hedera.node.app.service.contract.impl.exec.QueryComponent; import com.hedera.node.app.service.contract.impl.exec.QueryComponent.Factory; import com.hedera.node.app.service.token.ReadableAccountStore; @@ -65,6 +66,7 @@ public class ContractCallLocalHandler extends PaidQueryHandler { private final Provider provider; private final GasCalculator gasCalculator; private final InstantSource instantSource; + private final ContractServiceComponent contractServiceComponent; /** * Constructs a {@link ContractCreateHandler} with the given {@link Provider}, {@link GasCalculator} and {@link InstantSource}. @@ -77,10 +79,12 @@ public class ContractCallLocalHandler extends PaidQueryHandler { public ContractCallLocalHandler( @NonNull final Provider provider, @NonNull final GasCalculator gasCalculator, - @NonNull final InstantSource instantSource) { + @NonNull final InstantSource instantSource, + @NonNull final ContractServiceComponent contractServiceComponent) { this.provider = requireNonNull(provider); this.gasCalculator = requireNonNull(gasCalculator); this.instantSource = requireNonNull(instantSource); + this.contractServiceComponent = requireNonNull(contractServiceComponent); } @Override @@ -142,6 +146,7 @@ public Response findResponse(@NonNull final QueryContext context, @NonNull final requireNonNull(header); final var component = provider.get().create(context, instantSource.instant(), CONTRACT_CALL_LOCAL); + final var outcome = component.contextQueryProcessor().call(); final var responseHeader = outcome.isSuccess() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCreateHandler.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCreateHandler.java index c5b05858dd09..f6acb5e41001 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCreateHandler.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/ContractCreateHandler.java @@ -68,7 +68,7 @@ public ContractCreateHandler( @Override public void handle(@NonNull final HandleContext context) throws HandleException { // Create the transaction-scoped component - final var component = provider.get().create(context, CONTRACT_CREATE); + final var component = getTransactionComponent(context, CONTRACT_CREATE); // Run its in-scope transaction and get the outcome final var outcome = component.contextTransactionProcessor().call(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/EthereumTransactionHandler.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/EthereumTransactionHandler.java index f93e8e890cac..1aab358de0bc 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/EthereumTransactionHandler.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/handlers/EthereumTransactionHandler.java @@ -155,7 +155,7 @@ public void pureChecks(@NonNull final TransactionBody txn) throws PreCheckExcept @Override public void handle(@NonNull final HandleContext context) throws HandleException { // Create the transaction-scoped component - final var component = provider.get().create(context, ETHEREUM_TRANSACTION); + final var component = getTransactionComponent(context, ETHEREUM_TRANSACTION); // Run its in-scope transaction and get the outcome final var outcome = component.contextTransactionProcessor().call(); @@ -180,7 +180,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException * @param context the handle context */ public void handleThrottled(@NonNull final HandleContext context) { - final var component = provider.get().create(context, ETHEREUM_TRANSACTION); + final var component = getTransactionComponent(context, ETHEREUM_TRANSACTION); final var ethTxData = requireNonNull(requireNonNull(component.hydratedEthTxData()).ethTxData()); context.savepointStack() diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/module-info.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/module-info.java index 67f84fa6aea4..768a559efc21 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/module-info.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/module-info.java @@ -30,6 +30,7 @@ requires com.google.protobuf; requires org.apache.commons.lang3; requires org.bouncycastle.provider; + requires org.jetbrains.annotations; requires static com.github.spotbugs.annotations; requires static java.compiler; diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/metrics/ContractMetricsTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/metrics/ContractMetricsTest.java index b47b70bfac03..623ee2b5f759 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/metrics/ContractMetricsTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/metrics/ContractMetricsTest.java @@ -22,6 +22,7 @@ import com.hedera.hapi.node.base.HederaFunctionality; import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.config.data.ContractsConfig; import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; import com.swirlds.common.metrics.config.MetricsConfig; @@ -47,9 +48,12 @@ public class ContractMetricsTest { @Mock private ContractsConfig contractsConfig; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + public @NonNull ContractMetrics getSubject() { - final var contractMetrics = new ContractMetrics(metricsSupplier, () -> contractsConfig); - contractMetrics.createContractMetrics(); + final var contractMetrics = + new ContractMetrics(metricsSupplier, () -> contractsConfig, systemContractMethodRegistry); + contractMetrics.createContractPrimaryMetrics(); return contractMetrics; } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/CallAttemptHelpers.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/CallAttemptHelpers.java index feb1f391b644..5848385ce9eb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/CallAttemptHelpers.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/CallAttemptHelpers.java @@ -28,6 +28,8 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.test.TestHelpers; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -55,7 +57,8 @@ public static HtsCallAttempt prepareHtsAttemptWithSelector( final HederaWorldUpdater.Enhancement enhancement, final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, - final SystemContractGasCalculator gasCalculator) { + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { final var input = Bytes.wrap(function.selector()); return new HtsCallAttempt( @@ -69,6 +72,32 @@ public static HtsCallAttempt prepareHtsAttemptWithSelector( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HtsCallAttempt prepareHtsAttemptWithSelector( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { + final var input = Bytes.wrap(systemContractMethod.selector()); + + return new HtsCallAttempt( + input, + OWNER_BESU_ADDRESS, + OWNER_BESU_ADDRESS, + false, + enhancement, + DEFAULT_CONFIG, + addressIdConverter, + verificationStrategies, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, false); } @@ -87,7 +116,8 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirect( final HederaWorldUpdater.Enhancement enhancement, final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, - final SystemContractGasCalculator gasCalculator) { + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { final var input = TestHelpers.bytesForRedirect(function.selector(), NON_SYSTEM_LONG_ZERO_ADDRESS); return new HtsCallAttempt( @@ -101,6 +131,32 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirect( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirect( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { + final var input = TestHelpers.bytesForRedirect(systemContractMethod.selector(), NON_SYSTEM_LONG_ZERO_ADDRESS); + + return new HtsCallAttempt( + input, + OWNER_BESU_ADDRESS, + OWNER_BESU_ADDRESS, + false, + enhancement, + DEFAULT_CONFIG, + addressIdConverter, + verificationStrategies, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, false); } @@ -121,6 +177,7 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirectWithConfig( final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { final var input = TestHelpers.bytesForRedirect(function.selector(), NON_SYSTEM_LONG_ZERO_ADDRESS); @@ -135,6 +192,33 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirectWithConfig( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HtsCallAttempt prepareHtsAttemptWithSelectorForRedirectWithConfig( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, + final Configuration config) { + final var input = TestHelpers.bytesForRedirect(systemContractMethod.selector(), NON_SYSTEM_LONG_ZERO_ADDRESS); + + return new HtsCallAttempt( + input, + OWNER_BESU_ADDRESS, + OWNER_BESU_ADDRESS, + false, + enhancement, + config, + addressIdConverter, + verificationStrategies, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, false); } @@ -155,6 +239,7 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorAndCustomConfig( final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { final var input = Bytes.wrap(function.selector()); @@ -169,6 +254,33 @@ public static HtsCallAttempt prepareHtsAttemptWithSelectorAndCustomConfig( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HtsCallAttempt prepareHtsAttemptWithSelectorAndCustomConfig( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, + final Configuration config) { + final var input = Bytes.wrap(systemContractMethod.selector()); + + return new HtsCallAttempt( + input, + OWNER_BESU_ADDRESS, + OWNER_BESU_ADDRESS, + false, + enhancement, + config, + addressIdConverter, + verificationStrategies, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, false); } @@ -189,7 +301,8 @@ public static HasCallAttempt prepareHasAttemptWithSelector( final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, final SignatureVerifier signatureVerifier, - final SystemContractGasCalculator gasCalculator) { + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { return prepareHasAttemptWithSelectorAndCustomConfig( function, translator, @@ -198,6 +311,28 @@ public static HasCallAttempt prepareHasAttemptWithSelector( verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, + DEFAULT_CONFIG); + } + + public static HasCallAttempt prepareHasAttemptWithSelector( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SignatureVerifier signatureVerifier, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry) { + return prepareHasAttemptWithSelectorAndCustomConfig( + systemContractMethod, + translator, + enhancement, + addressIdConverter, + verificationStrategies, + signatureVerifier, + gasCalculator, + systemContractMethodRegistry, DEFAULT_CONFIG); } @@ -220,6 +355,7 @@ public static HasCallAttempt prepareHasAttemptWithSelectorAndCustomConfig( final VerificationStrategies verificationStrategies, final SignatureVerifier signatureVerifier, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { return prepareHasAttemptWithSelectorAndInputAndCustomConfig( function, @@ -230,6 +366,30 @@ public static HasCallAttempt prepareHasAttemptWithSelectorAndCustomConfig( verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, + config); + } + + public static HasCallAttempt prepareHasAttemptWithSelectorAndCustomConfig( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SignatureVerifier signatureVerifier, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, + final Configuration config) { + return prepareHasAttemptWithSelectorAndInputAndCustomConfig( + systemContractMethod, + TestHelpers.bytesForRedirectAccount(systemContractMethod.selector(), NON_SYSTEM_LONG_ZERO_ADDRESS), + translator, + enhancement, + addressIdConverter, + verificationStrategies, + signatureVerifier, + gasCalculator, + systemContractMethodRegistry, config); } @@ -254,6 +414,33 @@ public static HasCallAttempt prepareHasAttemptWithSelectorAndInputAndCustomConfi final VerificationStrategies verificationStrategies, final SignatureVerifier signatureVerifier, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, + final Configuration config) { + return new HasCallAttempt( + input, + OWNER_BESU_ADDRESS, + false, + enhancement, + config, + addressIdConverter, + verificationStrategies, + signatureVerifier, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HasCallAttempt prepareHasAttemptWithSelectorAndInputAndCustomConfig( + final SystemContractMethod systemContractMethod, + final Bytes input, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SignatureVerifier signatureVerifier, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { return new HasCallAttempt( input, @@ -266,6 +453,7 @@ public static HasCallAttempt prepareHasAttemptWithSelectorAndInputAndCustomConfi signatureVerifier, gasCalculator, List.of(translator), + systemContractMethodRegistry, false); } @@ -286,6 +474,7 @@ public static HssCallAttempt prepareHssAttemptWithSelectorAndCustomConfig( final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { final var input = Bytes.wrap(function.selector()); @@ -299,6 +488,32 @@ public static HssCallAttempt prepareHssAttemptWithSelectorAndCustomConfig( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, + false); + } + + public static HssCallAttempt prepareHssAttemptWithSelectorAndCustomConfig( + final SystemContractMethod systemContractMethod, + final CallTranslator translator, + final HederaWorldUpdater.Enhancement enhancement, + final AddressIdConverter addressIdConverter, + final VerificationStrategies verificationStrategies, + final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, + final Configuration config) { + final var input = Bytes.wrap(systemContractMethod.selector()); + + return new HssCallAttempt( + input, + OWNER_BESU_ADDRESS, + false, + enhancement, + config, + addressIdConverter, + verificationStrategies, + gasCalculator, + List.of(translator), + systemContractMethodRegistry, false); } @@ -309,6 +524,7 @@ public static HssCallAttempt prepareHssAttemptWithBytesAndCustomConfig( final AddressIdConverter addressIdConverter, final VerificationStrategies verificationStrategies, final SystemContractGasCalculator gasCalculator, + final SystemContractMethodRegistry systemContractMethodRegistry, final Configuration config) { return new HssCallAttempt( @@ -321,6 +537,7 @@ public static HssCallAttempt prepareHssAttemptWithBytesAndCustomConfig( verificationStrategies, gasCalculator, List.of(translator), + systemContractMethodRegistry, false); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HasSystemContractTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HasSystemContractTest.java index 7109dd2a083e..7c8a0f2b073b 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HasSystemContractTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HasSystemContractTest.java @@ -22,6 +22,7 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSamePrecompileResult; import static org.mockito.Mockito.when; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.HasSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallFactory; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; @@ -52,6 +53,9 @@ class HasSystemContractTest { @Mock private GasCalculator gasCalculator; + @Mock + private ContractMetrics contractMetrics; + private MockedStatic frameUtils; private HasSystemContract subject; @@ -60,7 +64,7 @@ class HasSystemContractTest { @BeforeEach void setUp() { frameUtils = Mockito.mockStatic(FrameUtils.class); - subject = new HasSystemContract(gasCalculator, attemptFactory); + subject = new HasSystemContract(gasCalculator, attemptFactory, contractMetrics); } @AfterEach diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HssSystemContractTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HssSystemContractTest.java index 88be76d82ffb..97be59188de8 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HssSystemContractTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HssSystemContractTest.java @@ -22,6 +22,7 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSamePrecompileResult; import static org.mockito.Mockito.when; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.HssSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallFactory; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; @@ -52,6 +53,9 @@ class HssSystemContractTest { @Mock private GasCalculator gasCalculator; + @Mock + private ContractMetrics contractMetrics; + private MockedStatic frameUtils; private HssSystemContract subject; @@ -60,7 +64,7 @@ class HssSystemContractTest { @BeforeEach void setUp() { frameUtils = Mockito.mockStatic(FrameUtils.class); - subject = new HssSystemContract(gasCalculator, attemptFactory); + subject = new HssSystemContract(gasCalculator, attemptFactory, contractMetrics); } @AfterEach diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HtsSystemContractTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HtsSystemContractTest.java index 27a57285961a..eeb17fff55c5 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HtsSystemContractTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/HtsSystemContractTest.java @@ -29,6 +29,7 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.lenient; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.SystemContractOperations; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.HtsSystemContract; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.Call; @@ -78,6 +79,9 @@ class HtsSystemContractTest { @Mock private GasCalculator gasCalculator; + @Mock + private ContractMetrics contractMetrics; + private MockedStatic frameUtils; private HtsSystemContract subject; @@ -86,7 +90,7 @@ class HtsSystemContractTest { @BeforeEach void setUp() { frameUtils = Mockito.mockStatic(FrameUtils.class); - subject = new HtsSystemContract(gasCalculator, attemptFactory); + subject = new HtsSystemContract(gasCalculator, attemptFactory, contractMetrics); } @AfterEach diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallAttemptTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallAttemptTest.java index d27d040adf6e..fc3e6b399cf2 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallAttemptTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallAttemptTest.java @@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.BDDMockito.given; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; @@ -36,6 +37,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.test.TestHelpers; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -56,11 +58,18 @@ class HasCallAttemptTest extends CallTestBase { @Mock private AddressIdConverter addressIdConverter; + @Mock + private ContractMetrics contractMetrics; + private List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + @BeforeEach void setUp() { - callTranslators = List.of(new HbarAllowanceTranslator(), new HbarApproveTranslator()); + callTranslators = List.of( + new HbarAllowanceTranslator(systemContractMethodRegistry, contractMetrics), + new HbarApproveTranslator(systemContractMethodRegistry, contractMetrics)); } @Test @@ -80,6 +89,7 @@ void returnNullAccountIfAccountNotFound() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.redirectAccount()); } @@ -98,6 +108,7 @@ void invalidSelectorLeadsToMissingCall() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.asExecutableCall()); } @@ -122,6 +133,7 @@ void constructsHbarAllowanceProxy() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(HbarAllowanceCall.class, subject.asExecutableCall()); } @@ -148,6 +160,7 @@ void constructsHbarAllowanceDirect() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(HbarAllowanceCall.class, subject.asExecutableCall()); } @@ -174,6 +187,7 @@ void constructsHbarApproveProxy() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(HbarApproveCall.class, subject.asExecutableCall()); } @@ -201,6 +215,7 @@ void constructsHbarApproveDirect() { signatureVerifier, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(HbarApproveCall.class, subject.asExecutableCall()); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallFactoryTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallFactoryTest.java index 762cab3c5c75..deb62f8f05c0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallFactoryTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/HasCallFactoryTest.java @@ -30,6 +30,7 @@ import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallAddressChecks; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallFactory; @@ -38,6 +39,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.SyntheticIds; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -77,11 +79,16 @@ class HasCallFactoryTest extends CallTestBase { @Mock private MessageFrame initialFrame; - private Deque stack = new ArrayDeque<>(); + private final Deque stack = new ArrayDeque<>(); @Mock private ProxyWorldUpdater updater; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private HasCallFactory subject; @BeforeEach @@ -91,7 +98,8 @@ void setUp() { addressChecks, verificationStrategies, signatureVerifier, - List.of(new HbarAllowanceTranslator())); + List.of(new HbarAllowanceTranslator(systemContractMethodRegistry, contractMetrics)), + systemContractMethodRegistry); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/evmaddressalias/EvmAddressAliasTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/evmaddressalias/EvmAddressAliasTranslatorTest.java index 6e32d80b0db6..f39eb385dcda 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/evmaddressalias/EvmAddressAliasTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/evmaddressalias/EvmAddressAliasTranslatorTest.java @@ -22,18 +22,18 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelector; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias.EvmAddressAliasCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias.EvmAddressAliasTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import org.apache.tuweni.bytes.Bytes; @@ -66,11 +66,16 @@ class EvmAddressAliasTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private EvmAddressAliasTranslator subject; @BeforeEach void setUp() { - subject = new EvmAddressAliasTranslator(); + subject = new EvmAddressAliasTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -83,8 +88,9 @@ void matchesEvmAddressAlias() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); assertEquals("0xdea3d081" /*copied from HIP-632*/, "0x" + EVM_ADDRESS_ALIAS.selectorHex()); } @@ -98,8 +104,9 @@ void failsOnInvalidSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarAllowance/HbarAllowanceTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarAllowance/HbarAllowanceTranslatorTest.java index 90dd7017d092..a96d7ea677c3 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarAllowance/HbarAllowanceTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarAllowance/HbarAllowanceTranslatorTest.java @@ -25,18 +25,18 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.UNAUTHORIZED_SPENDER_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelector; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarallowance.HbarAllowanceCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarallowance.HbarAllowanceTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import org.apache.tuweni.bytes.Bytes; @@ -69,11 +69,16 @@ public class HbarAllowanceTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private HbarAllowanceTranslator subject; @BeforeEach void setUp() { - subject = new HbarAllowanceTranslator(); + subject = new HbarAllowanceTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -86,8 +91,9 @@ void matchesHbarAllowance() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); attempt = prepareHasAttemptWithSelector( HBAR_ALLOWANCE_PROXY, @@ -96,8 +102,9 @@ void matchesHbarAllowance() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -110,8 +117,9 @@ void failsOnInvalidSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarApprove/HbarApproveTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarApprove/HbarApproveTranslatorTest.java index 706aa22cba96..7eba86882d9c 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarApprove/HbarApproveTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hbarApprove/HbarApproveTranslatorTest.java @@ -25,18 +25,18 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.UNAUTHORIZED_SPENDER_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelector; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import java.math.BigInteger; @@ -70,11 +70,16 @@ public class HbarApproveTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private HbarApproveTranslator subject; @BeforeEach void setUp() { - subject = new HbarApproveTranslator(); + subject = new HbarApproveTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -87,8 +92,9 @@ void matchesHbarApprove() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); attempt = prepareHasAttemptWithSelector( HBAR_APPROVE_PROXY, @@ -97,8 +103,9 @@ void matchesHbarApprove() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -111,8 +118,9 @@ void failsOnInvalidSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslatorTest.java index b70092cde1e9..4f94ffb62ebf 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/hederaaccountnumalias/HederaAccountNumAliasTranslatorTest.java @@ -22,18 +22,18 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias.HederaAccountNumAliasCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hederaaccountnumalias.HederaAccountNumAliasTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import org.apache.tuweni.bytes.Bytes; @@ -67,11 +67,16 @@ public class HederaAccountNumAliasTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private HederaAccountNumAliasTranslator subject; @BeforeEach void setUp() { - subject = new HederaAccountNumAliasTranslator(); + subject = new HederaAccountNumAliasTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -84,8 +89,9 @@ void matchesHederaAccountNumAlias() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); assertEquals("0xbbf12d2e" /*copied from HIP-632*/, "0x" + HEDERA_ACCOUNT_NUM_ALIAS.selectorHex()); } @@ -99,8 +105,9 @@ void failsOnInvalidSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslatorTest.java index fd2ab6294a5c..93c485660a01 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorized/IsAuthorizedTranslatorTest.java @@ -24,19 +24,19 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelectorAndCustomConfig; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelectorAndInputAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCalculator; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isauthorized.IsAuthorizedCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isauthorized.IsAuthorizedTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.exec.v051.Version051FeatureFlags; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -78,12 +78,18 @@ public class IsAuthorizedTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsAuthorizedTranslator subject; @BeforeEach void setUp() { final var featureFlags = new Version051FeatureFlags(); - subject = new IsAuthorizedTranslator(featureFlags, customGasCalculator); + subject = new IsAuthorizedTranslator( + featureFlags, customGasCalculator, systemContractMethodRegistry, contractMetrics); given(enhancement.nativeOperations()).willReturn(nativeOperations); } @@ -98,8 +104,9 @@ void matchesIsAuthorizedWhenEnabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -112,8 +119,9 @@ void doesNotMatchIsAuthorizedWhenDisabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(false)); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -126,8 +134,9 @@ void failsOnInvalidSelector() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -144,6 +153,7 @@ void callFromIsAuthorizedTest() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); final var call = subject.callFrom(attempt); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslatorTest.java index 658702406105..2f1d3869b1e5 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isauthorizedraw/IsAuthorizedRawTranslatorTest.java @@ -23,20 +23,21 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.signature; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCalculator; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isauthorizedraw.IsAuthorizedRawCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isauthorizedraw.IsAuthorizedRawTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.exec.v051.Version051FeatureFlags; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -78,12 +79,18 @@ public class IsAuthorizedRawTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsAuthorizedRawTranslator subject; @BeforeEach void setUp() { final var featureFlags = new Version051FeatureFlags(); - subject = new IsAuthorizedRawTranslator(featureFlags, customGasCalculator); + subject = new IsAuthorizedRawTranslator( + featureFlags, customGasCalculator, systemContractMethodRegistry, contractMetrics); } @Test @@ -97,8 +104,9 @@ void matchesIsAuthorizedRawWhenEnabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -112,8 +120,9 @@ void doesNotMatchIsAuthorizedRawWhenDisabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(false)); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -127,8 +136,9 @@ void failsOnInvalidSelector() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -144,8 +154,8 @@ void callFromIsAuthorizedRawTest() { private void givenCommonForCall(Bytes inputBytes) { given(attempt.inputBytes()).willReturn(inputBytes.toArray()); - given(attempt.isSelector(any())).willReturn(true); given(attempt.enhancement()).willReturn(enhancement); + given(attempt.isSelector((SystemContractMethod) any())).willReturn(true); given(attempt.systemContractGasCalculator()).willReturn(gasCalculator); given(attempt.signatureVerifier()).willReturn(signatureVerifier); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslatorTest.java index bdd6c1442289..542be26e6309 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/isvalidalias/IsValidAliasTranslatorTest.java @@ -22,18 +22,18 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias.IsValidAliasCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias.IsValidAliasTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import org.apache.tuweni.bytes.Bytes; @@ -67,11 +67,16 @@ public class IsValidAliasTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsValidAliasTranslator subject; @BeforeEach void setUp() { - subject = new IsValidAliasTranslator(); + subject = new IsValidAliasTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -84,8 +89,9 @@ void matchesIsValidAliasSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); assertEquals("0x308ef301" /*copied from HIP-632*/, "0x" + IS_VALID_ALIAS.selectorHex()); } @@ -99,8 +105,9 @@ void failsOnInvalidSelector() { addressIdConverter, verificationStrategies, signatureVerifier, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslatorTest.java index 8a05d30fd662..8167f9fae1a0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/has/setunlimitedautoassociations/SetUnlimitedAutoAssociationsTranslatorTest.java @@ -19,17 +19,17 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.setunlimitedautoassociations.SetUnlimitedAutoAssociationsTranslator.SET_UNLIMITED_AUTO_ASSOC; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHasAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.HasCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.setunlimitedautoassociations.SetUnlimitedAutoAssociationsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.setunlimitedautoassociations.SetUnlimitedAutoAssociationsTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.signatures.SignatureVerifier; import com.hedera.node.config.data.ContractsConfig; @@ -70,11 +70,16 @@ class SetUnlimitedAutoAssociationsTranslatorTest { @Mock private ContractsConfig contractsConfig; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private SetUnlimitedAutoAssociationsTranslator subject; @BeforeEach void setUp() { - subject = new SetUnlimitedAutoAssociationsTranslator(); + subject = new SetUnlimitedAutoAssociationsTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -91,8 +96,9 @@ void matchesWhenEnabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -109,8 +115,9 @@ void matchesWhenDisabled() { verificationStrategies, signatureVerifier, gasCalculator, + systemContractMethodRegistry, configuration); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallAttemptTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallAttemptTest.java index 01227c9d8038..179f389f24fb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallAttemptTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallAttemptTest.java @@ -23,11 +23,13 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.BDDMockito.given; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.HssCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.signschedule.SignScheduleTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.test.TestHelpers; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import java.util.List; @@ -44,9 +46,14 @@ class HssCallAttemptTest extends CallTestBase { private List> callTranslators; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + @BeforeEach void setUp() { - callTranslators = List.of(new SignScheduleTranslator()); + callTranslators = List.of(new SignScheduleTranslator(systemContractMethodRegistry, contractMetrics)); } @Test @@ -64,6 +71,7 @@ void returnNullScheduleIfScheduleNotFound() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.redirectScheduleTxn()); } @@ -81,6 +89,7 @@ void invalidSelectorLeadsToMissingCall() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.asExecutableCall()); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallFactoryTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallFactoryTest.java index daaa6e98e116..c8b0e91d684b 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallFactoryTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/HssCallFactoryTest.java @@ -31,6 +31,7 @@ import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.state.schedule.Schedule; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallAddressChecks; @@ -40,6 +41,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.SyntheticIds; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.app.spi.signatures.SignatureVerifier; @@ -80,7 +82,7 @@ class HssCallFactoryTest extends CallTestBase { @Mock private MessageFrame initialFrame; - private Deque stack = new ArrayDeque<>(); + private final Deque stack = new ArrayDeque<>(); @Mock private ProxyWorldUpdater updater; @@ -91,6 +93,11 @@ class HssCallFactoryTest extends CallTestBase { @Mock private Key maybeEthSenderKey; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private HssCallFactory subject; @BeforeEach @@ -100,7 +107,8 @@ void setUp() { addressChecks, verificationStrategies, signatureVerifier, - List.of(new SignScheduleTranslator())); + List.of(new SignScheduleTranslator(systemContractMethodRegistry, contractMetrics)), + systemContractMethodRegistry); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/signschedule/SignScheduleTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/signschedule/SignScheduleTranslatorTest.java index 421f8dffb082..b2589b88fc00 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/signschedule/SignScheduleTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hss/signschedule/SignScheduleTranslatorTest.java @@ -25,8 +25,6 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHssAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; @@ -38,6 +36,7 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.SystemContractOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; @@ -47,6 +46,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hss.signschedule.SignScheduleTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -102,16 +102,20 @@ class SignScheduleTranslatorTest { @Mock private ScheduleID scheduleID; + @Mock + ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private SignScheduleTranslator subject; @BeforeEach void setUp() { - subject = new SignScheduleTranslator(); + subject = new SignScheduleTranslator(systemContractMethodRegistry, contractMetrics); } @Test void testMatchesWhenSignScheduleEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractSignScheduleEnabled()).willReturn(true); attempt = prepareHssAttemptWithSelectorAndCustomConfig( @@ -121,18 +125,13 @@ void testMatchesWhenSignScheduleEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void testFailsMatchesWhenSignScheduleEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractSignScheduleEnabled()).willReturn(false); attempt = prepareHssAttemptWithSelectorAndCustomConfig( @@ -142,18 +141,13 @@ void testFailsMatchesWhenSignScheduleEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void testMatchesWhenAuthorizeScheduleEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractAuthorizeScheduleEnabled()).willReturn(true); attempt = prepareHssAttemptWithSelectorAndCustomConfig( @@ -163,18 +157,13 @@ void testMatchesWhenAuthorizeScheduleEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void testFailsMatchesWhenAuthorizeScheduleEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractAuthorizeScheduleEnabled()).willReturn(false); attempt = prepareHssAttemptWithSelectorAndCustomConfig( @@ -184,18 +173,13 @@ void testFailsMatchesWhenAuthorizeScheduleEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void testMatchesFailsOnRandomSelector() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractSignScheduleEnabled()).willReturn(true); attempt = prepareHssAttemptWithSelectorAndCustomConfig( @@ -205,13 +189,9 @@ void testMatchesFailsOnRandomSelector() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -234,6 +214,7 @@ void testScheduleIdForSignScheduleProxy() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // then: @@ -257,7 +238,14 @@ void testScheduleIdForAuthorizeScheduleProxy() { final var input = Bytes.wrapByteBuffer( SignScheduleTranslator.AUTHORIZE_SCHEDULE.encodeCall(Tuple.of(APPROVED_HEADLONG_ADDRESS))); attempt = prepareHssAttemptWithBytesAndCustomConfig( - input, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, configuration); + input, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry, + configuration); // then: final var call = subject.callFrom(attempt); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallAttemptTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallAttemptTest.java index cbaefda4b7d7..17bfa97e4995 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallAttemptTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallAttemptTest.java @@ -38,6 +38,7 @@ import com.hedera.hapi.node.token.TokenMintTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; @@ -71,6 +72,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.Erc20TransfersTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.Erc721TransferFromCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.Erc721TransferFromTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.test.TestHelpers; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.swirlds.common.utility.CommonUtils; @@ -103,24 +105,29 @@ class HtsCallAttemptTest extends CallTestBase { @Mock private MintDecoder mintDecoder; + @Mock + private ContractMetrics contractMetrics; + private List> callTranslators; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + @BeforeEach void setUp() { callTranslators = List.of( - new AssociationsTranslator(associationsDecoder), - new Erc20TransfersTranslator(), - new Erc721TransferFromTranslator(), - new MintTranslator(mintDecoder), - new ClassicTransfersTranslator(classicTransfersDecoder), - new BalanceOfTranslator(), - new IsApprovedForAllTranslator(), - new NameTranslator(), - new TotalSupplyTranslator(), - new SymbolTranslator(), - new TokenUriTranslator(), - new OwnerOfTranslator(), - new DecimalsTranslator()); + new AssociationsTranslator(associationsDecoder, systemContractMethodRegistry, contractMetrics), + new Erc20TransfersTranslator(systemContractMethodRegistry, contractMetrics), + new Erc721TransferFromTranslator(systemContractMethodRegistry, contractMetrics), + new MintTranslator(mintDecoder, systemContractMethodRegistry, contractMetrics), + new ClassicTransfersTranslator(classicTransfersDecoder, systemContractMethodRegistry, contractMetrics), + new BalanceOfTranslator(systemContractMethodRegistry, contractMetrics), + new IsApprovedForAllTranslator(systemContractMethodRegistry, contractMetrics), + new NameTranslator(systemContractMethodRegistry, contractMetrics), + new TotalSupplyTranslator(systemContractMethodRegistry, contractMetrics), + new SymbolTranslator(systemContractMethodRegistry, contractMetrics), + new TokenUriTranslator(systemContractMethodRegistry, contractMetrics), + new OwnerOfTranslator(systemContractMethodRegistry, contractMetrics), + new DecimalsTranslator(systemContractMethodRegistry, contractMetrics)); } @Test @@ -138,6 +145,7 @@ void nonLongZeroAddressesArentTokens() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.redirectToken()); verifyNoInteractions(nativeOperations); @@ -159,6 +167,7 @@ void invalidSelectorLeadsToMissingCall() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertNull(subject.asExecutableCall()); } @@ -178,6 +187,7 @@ void constructsDecimals() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(DecimalsCall.class, subject.asExecutableCall()); } @@ -197,6 +207,7 @@ void constructsTokenUri() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(TokenUriCall.class, subject.asExecutableCall()); } @@ -216,6 +227,7 @@ void constructsOwnerOf() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(OwnerOfCall.class, subject.asExecutableCall()); } @@ -238,6 +250,7 @@ void constructsBalanceOf() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(BalanceOfCall.class, subject.asExecutableCall()); } @@ -261,6 +274,7 @@ void constructsIsApprovedForAllErc() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(IsApprovedForAllCall.class, subject.asExecutableCall()); } @@ -282,6 +296,7 @@ void constructsIsApprovedForAllClassic() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(IsApprovedForAllCall.class, subject.asExecutableCall()); } @@ -301,6 +316,7 @@ void constructsTotalSupply() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(TotalSupplyCall.class, subject.asExecutableCall()); } @@ -320,6 +336,7 @@ void constructsName() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(NameCall.class, subject.asExecutableCall()); } @@ -339,6 +356,7 @@ void constructsSymbol() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(SymbolCall.class, subject.asExecutableCall()); } @@ -369,6 +387,7 @@ void constructsErc721TransferFromRedirectToNonfungible() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(Erc721TransferFromCall.class, subject.asExecutableCall()); } @@ -399,6 +418,7 @@ void constructsErc20TransferFromRedirectToFungible() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(Erc20TransfersCall.class, subject.asExecutableCall()); } @@ -426,6 +446,7 @@ void constructsErc20TransferRedirectToFungible() { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(Erc20TransfersCall.class, subject.asExecutableCall()); } @@ -479,6 +500,7 @@ void constructsAssociations(boolean useExplicitCall, boolean isRedirect, String verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(DispatchForResponseCodeHtsCall.class, subject.asExecutableCall()); @@ -542,6 +564,7 @@ void constructsClassicTransfers(String hexedSelector) { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(ClassicTransfersCall.class, subject.asExecutableCall()); @@ -613,6 +636,7 @@ void constructsMints(String hexedSelector, LinkedTokenType linkedTokenType) { verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); assertInstanceOf(DispatchForResponseCodeHtsCall.class, subject.asExecutableCall()); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallFactoryTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallFactoryTest.java index 3766b82242f3..784d57d13779 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallFactoryTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/HtsCallFactoryTest.java @@ -29,6 +29,7 @@ import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallAddressChecks; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -37,6 +38,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.balanceof.BalanceOfCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.balanceof.BalanceOfTranslator; import com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import java.util.ArrayDeque; @@ -76,12 +78,21 @@ class HtsCallFactoryTest extends CallTestBase { @Mock private ProxyWorldUpdater updater; + @Mock + private ContractMetrics contractMetrics; + private HtsCallFactory subject; + private SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + @BeforeEach void setUp() { subject = new HtsCallFactory( - syntheticIds, addressChecks, verificationStrategies, List.of(new BalanceOfTranslator())); + syntheticIds, + addressChecks, + verificationStrategies, + List.of(new BalanceOfTranslator(systemContractMethodRegistry, contractMetrics)), + systemContractMethodRegistry); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/airdrops/TokenAirdropTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/airdrops/TokenAirdropTranslatorTest.java index cd1d0d159f05..afb2149acdac 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/airdrops/TokenAirdropTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/airdrops/TokenAirdropTranslatorTest.java @@ -19,9 +19,8 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.airdrops.TokenAirdropTranslator.TOKEN_AIRDROP; import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -31,6 +30,7 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -39,6 +39,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.airdrops.TokenAirdropDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.airdrops.TokenAirdropTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.config.data.ContractsConfig; @@ -87,11 +88,16 @@ class TokenAirdropTranslatorTest extends CallTestBase { @Mock private AccountID payerId; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenAirdropTranslator translator; @BeforeEach void setUp() { - translator = new TokenAirdropTranslator(decoder); + translator = new TokenAirdropTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -103,8 +109,9 @@ void matchesWhenAirdropEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(true)); - assertTrue(translator.matches(attempt)); + assertThat(translator.identifyMethod(attempt)).isPresent(); } @Test @@ -116,8 +123,9 @@ void doesNotMatchWhenAirdropDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, getTestConfiguration(false)); - assertFalse(translator.matches(attempt)); + assertThat(translator.identifyMethod(attempt)).isEmpty(); } @Test @@ -131,11 +139,9 @@ void matchesFailsForRandomSelector() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - boolean result = translator.matches(attempt); - - assertFalse(result); + assertThat(translator.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/allowance/GetAllowanceTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/allowance/GetAllowanceTranslatorTest.java index e5eb55a61a3f..cf79aa7425a0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/allowance/GetAllowanceTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/allowance/GetAllowanceTranslatorTest.java @@ -24,17 +24,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.OWNER_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.allowance.GetAllowanceCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.allowance.GetAllowanceTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -63,25 +63,43 @@ public class GetAllowanceTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + private GetAllowanceTranslator subject; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + @BeforeEach void setUp() { - subject = new GetAllowanceTranslator(); + subject = new GetAllowanceTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesGetAllowance() { attempt = prepareHtsAttemptWithSelector( - GET_ALLOWANCE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + GET_ALLOWANCE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesERCGetAllowance() { attempt = prepareHtsAttemptWithSelector( - ERC_GET_ALLOWANCE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + ERC_GET_ALLOWANCE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); + ; } @Test @@ -92,8 +110,9 @@ void failsOnInvalidSelector() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/burn/BurnTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/burn/BurnTranslatorTest.java index dbc41b5506d4..c24e45080467 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/burn/BurnTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/burn/BurnTranslatorTest.java @@ -20,15 +20,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnTranslator.BURN_TOKEN_V2; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateTranslator.TOKEN_UPDATE_INFO_FUNCTION_V3; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -54,27 +55,44 @@ class BurnTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private BurnTranslator subject; private final BurnDecoder decoder = new BurnDecoder(); @BeforeEach void setUp() { - subject = new BurnTranslator(decoder); + subject = new BurnTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesBurnTokenV1() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V1, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + BURN_TOKEN_V1, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesBurnTokenV2() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -85,7 +103,8 @@ void matchFailsOnInvalidSelector() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoderTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoderTest.java index a0a699bc70f6..6f7acfdc20e4 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoderTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropDecoderTest.java @@ -18,7 +18,7 @@ import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_TOKEN_ID; import static com.hedera.hapi.node.base.ResponseCodeEnum.PENDING_AIRDROP_ID_LIST_TOO_LONG; -import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropTranslator.CANCEL_AIRDROP; +import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropTranslator.CANCEL_AIRDROPS; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropTranslator.HRC_CANCEL_AIRDROP_FT; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropTranslator.HRC_CANCEL_AIRDROP_NFT; import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN; @@ -99,7 +99,7 @@ void cancelAirdropDecoder1FTTest() { .willReturn(SENDER_ID); given(addressIdConverter.convert(OWNER_ACCOUNT_AS_ADDRESS)).willReturn(OWNER_ID); - final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, @@ -133,7 +133,7 @@ void failsIfPendingAirdropsAboveLimit() { FUNGIBLE_TOKEN_HEADLONG_ADDRESS, 0L); final var encoded = - Bytes.wrapByteBuffer(CANCEL_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] {tuple, tuple, tuple}))); + Bytes.wrapByteBuffer(CANCEL_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] {tuple, tuple, tuple}))); given(attempt.inputBytes()).willReturn(encoded.toArrayUnsafe()); assertThatExceptionOfType(HandleException.class) @@ -150,7 +150,7 @@ void failsIfTokenIsNull() { .willReturn(SENDER_ID); given(addressIdConverter.convert(OWNER_ACCOUNT_AS_ADDRESS)).willReturn(OWNER_ID); - final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, @@ -173,7 +173,7 @@ void cancelAirdropDecoder1NFTTest() { .willReturn(SENDER_ID); given(addressIdConverter.convert(OWNER_ACCOUNT_AS_ADDRESS)).willReturn(OWNER_ID); - final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CANCEL_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslatorTest.java index 26568e3d7d0a..95c91ced909b 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/cancelairdrops/TokenCancelAirdropTranslatorTest.java @@ -19,9 +19,8 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirectWithConfig; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; @@ -31,6 +30,7 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; @@ -40,6 +40,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.cancelairdrops.TokenCancelAirdropTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -88,37 +89,37 @@ class TokenCancelAirdropTranslatorTest { @Mock private AccountID payerId; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenCancelAirdropTranslator subject; @BeforeEach void setUp() { - subject = new TokenCancelAirdropTranslator(decoder); + subject = new TokenCancelAirdropTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesHTSCancelAirdropEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenCancelAirdropTranslator.CANCEL_AIRDROP, + TokenCancelAirdropTranslator.CANCEL_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsOnWrongSelector() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( @@ -128,39 +129,31 @@ void matchesFailsOnWrongSelector() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesHTSCancelAirdropDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(false); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenCancelAirdropTranslator.CANCEL_AIRDROP, + TokenCancelAirdropTranslator.CANCEL_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesHRCCancelFTAirdropEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -171,18 +164,14 @@ void matchesHRCCancelFTAirdropEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesHRCCancelAirdropDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -193,18 +182,14 @@ void matchesHRCCancelAirdropDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesHRCCancelNFTAirdropEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -215,18 +200,14 @@ void matchesHRCCancelNFTAirdropEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesHRCCancelNFTAirdropDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractCancelAirdropsEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -237,12 +218,10 @@ void matchesHRCCancelNFTAirdropDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - // when: - boolean matches = subject.matches(attempt); - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -263,12 +242,13 @@ void callFromHtsCancelAirdrop() { given(verificationStrategies.activatingOnlyContractKeysFor(any(), anyBoolean(), any())) .willReturn(verificationStrategy); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenCancelAirdropTranslator.CANCEL_AIRDROP, + TokenCancelAirdropTranslator.CANCEL_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -292,6 +272,7 @@ void callFromHRCCancelFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -315,6 +296,7 @@ void callFromHRCCancelNFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoderTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoderTest.java index bcb244eb2303..3724cfb0bbc8 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoderTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropDecoderTest.java @@ -17,7 +17,7 @@ package com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.hts.claimairdrops; import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_TOKEN_ID; -import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropTranslator.CLAIM_AIRDROP; +import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropTranslator.CLAIM_AIRDROPS; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropTranslator.HRC_CLAIM_AIRDROP_FT; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropTranslator.HRC_CLAIM_AIRDROP_NFT; import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN; @@ -99,7 +99,7 @@ void claimAirdropDecoder1FTTest() { given(addressIdConverter.convert(asHeadlongAddress(SENDER_ID.accountNum()))) .willReturn(SENDER_ID); - final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, @@ -129,7 +129,7 @@ void failsIfPendingAirdropsAboveLimit() { given(configuration.getConfigData(TokensConfig.class)).willReturn(tokensConfig); given(tokensConfig.maxAllowedPendingAirdropsToClaim()).willReturn(10); - final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, @@ -204,7 +204,7 @@ void failsIfTokenIsNull() { .willReturn(SENDER_ID); given(addressIdConverter.convert(OWNER_ACCOUNT_AS_ADDRESS)).willReturn(OWNER_ID); - final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, @@ -252,7 +252,7 @@ void claimAirdropDecoder1NFTTest() { .willReturn(SENDER_ID); given(addressIdConverter.convert(OWNER_ACCOUNT_AS_ADDRESS)).willReturn(OWNER_ID); - final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROP.encodeCall(Tuple.singleton(new Tuple[] { + final var encoded = Bytes.wrapByteBuffer(CLAIM_AIRDROPS.encodeCall(Tuple.singleton(new Tuple[] { Tuple.of( asHeadlongAddress(SENDER_ID.accountNum()), OWNER_ACCOUNT_AS_ADDRESS, diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslatorTest.java index ee5655def64e..fda974fad88f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/claimairdrops/TokenClaimAirdropTranslatorTest.java @@ -19,9 +19,8 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirectWithConfig; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; @@ -32,6 +31,7 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; @@ -41,6 +41,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.claimairdrops.TokenClaimAirdropTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -89,37 +90,36 @@ class TokenClaimAirdropTranslatorTest { @Mock private AccountID payerId; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenClaimAirdropTranslator subject; @BeforeEach void setUp() { - subject = new TokenClaimAirdropTranslator(decoder); + subject = new TokenClaimAirdropTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void testMatchesWhenClaimAirdropEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenClaimAirdropTranslator.CLAIM_AIRDROP, + TokenClaimAirdropTranslator.CLAIM_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void testMatchesFailsOnRandomSelector() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( @@ -129,40 +129,29 @@ void testMatchesFailsOnRandomSelector() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void testMatchesWhenClaimAirdropDisabled() { - // given: - given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(false); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenClaimAirdropTranslator.CLAIM_AIRDROP, + TokenClaimAirdropTranslator.CLAIM_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void testMatchesHRCClaimFT() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -173,18 +162,13 @@ void testMatchesHRCClaimFT() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void testMatchesHRCClaimNFT() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -195,18 +179,13 @@ void testMatchesHRCClaimNFT() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void testMatchesHRCClaimFTDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -217,18 +196,13 @@ void testMatchesHRCClaimFTDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void testMatchesHRCClaimNFTDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractClaimAirdropsEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -239,13 +213,9 @@ void testMatchesHRCClaimNFTDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -255,12 +225,13 @@ void testCallFromForClassic() { given(verificationStrategies.activatingOnlyContractKeysFor(any(), anyBoolean(), any())) .willReturn(verificationStrategy); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - TokenClaimAirdropTranslator.CLAIM_AIRDROP, + TokenClaimAirdropTranslator.CLAIM_AIRDROPS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -284,6 +255,7 @@ void callFromHRCClaimFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -307,6 +279,7 @@ void callFromHRCCancelNFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/create/CreateTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/create/CreateTranslatorTest.java index 2218e31402b0..9ce8d3939729 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/create/CreateTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/create/CreateTranslatorTest.java @@ -53,11 +53,10 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.hts.create.CreateTestHelper.CREATE_NON_FUNGIBLE_WITH_META_AND_FEES_TUPLE; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.hts.create.CreateTestHelper.CREATE_NON_FUNGIBLE_WITH_META_TUPLE; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -65,6 +64,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.create.ClassicCreatesCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.create.CreateDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.create.CreateTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.config.data.ContractsConfig; @@ -106,13 +106,18 @@ public class CreateTranslatorTest extends CallTestBase { @Mock Configuration configuration; - private CreateDecoder decoder = new CreateDecoder(); + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + + private final CreateDecoder decoder = new CreateDecoder(); private CreateTranslator subject; @BeforeEach void setUp() { - subject = new CreateTranslator(decoder); + subject = new CreateTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -123,8 +128,9 @@ void matchesCreateFungibleTokenV1() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -135,8 +141,9 @@ void matchesCreateFungibleTokenV2() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -147,8 +154,9 @@ void matchesCreateFungibleTokenV3() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -161,8 +169,9 @@ void matchesCreateFungibleTokenWithMetadata() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -173,8 +182,9 @@ void matchesCreateFungibleTokenWithCustomFeesV1() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -185,8 +195,9 @@ void matchesCreateFungibleTokenWithCustomFeesV2() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -197,8 +208,9 @@ void matchesCreateFungibleTokenWithCustomFeesV3() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -211,8 +223,9 @@ void matchesCreateFungibleTokenWithMetadataAndCustomFees() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -223,8 +236,9 @@ void matchesCreateNonFungibleTokenV1() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -235,8 +249,9 @@ void matchesCreateNonFungibleTokenV2() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -247,8 +262,9 @@ void matchesCreateNonFungibleTokenV3() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -261,8 +277,9 @@ void matchesCreateNonFungibleTokenWithMetadata() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -273,8 +290,9 @@ void matchesCreateNonFungibleTokenWithCustomFeesV1() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -285,8 +303,9 @@ void matchesCreateNonFungibleTokenWithCustomFeesV2() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -297,8 +316,9 @@ void matchesCreateNonFungibleTokenWithCustomFeesV3() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -311,15 +331,22 @@ void matchesCreateNonFungibleTokenWithMetadataAndCustomFees() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void falseOnInvalidSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslatorTest.java index 9fc99c88e126..00a6d4069bf7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/customfees/TokenCustomFeesTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.customfees.TokenCustomFeesCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.customfees.TokenCustomFeesTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class TokenCustomFeesTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenCustomFeesTranslator subject; @BeforeEach void setUp() { - subject = new TokenCustomFeesTranslator(); + subject = new TokenCustomFeesTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesTokenCustomFeesTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - TOKEN_CUSTOM_FEES, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + TOKEN_CUSTOM_FEES, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslatorTest.java index 298efd01b86e..d0ee02ee76d9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultfreezestatus/DefaultFreezeStatusTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultfreezestatus.DefaultFreezeStatusCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultfreezestatus.DefaultFreezeStatusTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class DefaultFreezeStatusTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private DefaultFreezeStatusTranslator subject; @BeforeEach void setUp() { - subject = new DefaultFreezeStatusTranslator(); + subject = new DefaultFreezeStatusTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesDefaultFreezeTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - DEFAULT_FREEZE_STATUS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + DEFAULT_FREEZE_STATUS, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslatorTest.java index 659ec1afd115..01162155c886 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/defaultkycstatus/DefaultKycStatusTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultkycstatus.DefaultKycStatusCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.defaultkycstatus.DefaultKycStatusTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class DefaultKycStatusTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private DefaultKycStatusTranslator subject; @BeforeEach void setUp() { - subject = new DefaultKycStatusTranslator(); + subject = new DefaultKycStatusTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesDefaultKycTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - DEFAULT_KYC_STATUS, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + DEFAULT_KYC_STATUS, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/delete/DeleteTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/delete/DeleteTranslatorTest.java index f7197a42a9b4..01e8439f0077 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/delete/DeleteTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/delete/DeleteTranslatorTest.java @@ -22,19 +22,19 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.NON_SYSTEM_ACCOUNT_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.delete.DeleteTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -63,25 +63,42 @@ class DeleteTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private DeleteTranslator subject; @BeforeEach void setUp() { - subject = new DeleteTranslator(); + subject = new DeleteTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesDelete() { attempt = prepareHtsAttemptWithSelector( - DELETE_TOKEN, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + DELETE_TOKEN, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslatorTest.java index f7b385fedb4d..3776b5d5034c 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/freeze/FreezeUnfreezeTranslatorTest.java @@ -20,15 +20,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeTranslator.FREEZE; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeTranslator.UNFREEZE; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -54,32 +55,55 @@ class FreezeUnfreezeTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final FreezeUnfreezeDecoder decoder = new FreezeUnfreezeDecoder(); private FreezeUnfreezeTranslator subject; @BeforeEach void setUp() { - subject = new FreezeUnfreezeTranslator(decoder); + subject = new FreezeUnfreezeTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void freezeMatches() { attempt = prepareHtsAttemptWithSelector( - FREEZE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + FREEZE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void unfreezeMatches() { attempt = prepareHtsAttemptWithSelector( - UNFREEZE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + UNFREEZE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void falseOnInvalidSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCallTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCallTest.java index e05e758382e9..50fde61c593a 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCallTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoCallTest.java @@ -63,7 +63,12 @@ void returnsFungibleTokenInfoStatusForPresentToken() { when(ledgerConfig.id()).thenReturn(expectedLedgerId); final var subject = new FungibleTokenInfoCall( - gasCalculator, mockEnhancement(), false, FUNGIBLE_EVERYTHING_TOKEN, config, FUNGIBLE_TOKEN_INFO); + gasCalculator, + mockEnhancement(), + false, + FUNGIBLE_EVERYTHING_TOKEN, + config, + FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -106,7 +111,12 @@ void returnsFungibleTokenInfoStatusForPresentTokenV2() { when(ledgerConfig.id()).thenReturn(expectedLedgerId); final var subject = new FungibleTokenInfoCall( - gasCalculator, mockEnhancement(), false, FUNGIBLE_EVERYTHING_TOKEN_V2, config, FUNGIBLE_TOKEN_INFO_V2); + gasCalculator, + mockEnhancement(), + false, + FUNGIBLE_EVERYTHING_TOKEN_V2, + config, + FUNGIBLE_TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); @@ -150,8 +160,8 @@ void returnsFungibleTokenInfoStatusForMissingToken() { final var expectedLedgerId = com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01"); when(ledgerConfig.id()).thenReturn(expectedLedgerId); - final var subject = - new FungibleTokenInfoCall(gasCalculator, mockEnhancement(), false, null, config, FUNGIBLE_TOKEN_INFO); + final var subject = new FungibleTokenInfoCall( + gasCalculator, mockEnhancement(), false, null, config, FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -192,8 +202,8 @@ void returnsFungibleTokenInfoStatusForMissingTokenStaticCall() { when(config.getConfigData(LedgerConfig.class)).thenReturn(ledgerConfig); when(ledgerConfig.id()).thenReturn(com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01")); - final var subject = - new FungibleTokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, FUNGIBLE_TOKEN_INFO); + final var subject = new FungibleTokenInfoCall( + gasCalculator, mockEnhancement(), true, null, config, FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -206,8 +216,8 @@ void returnsFungibleTokenInfoStatusForMissingTokenStaticCallV2() { when(config.getConfigData(LedgerConfig.class)).thenReturn(ledgerConfig); when(ledgerConfig.id()).thenReturn(com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01")); - final var subject = - new FungibleTokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, FUNGIBLE_TOKEN_INFO_V2); + final var subject = new FungibleTokenInfoCall( + gasCalculator, mockEnhancement(), true, null, config, FUNGIBLE_TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslatorTest.java index 7e2ea0055dcd..0ac9f0bfa16e 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/fungibletokeninfo/FungibleTokenInfoTranslatorTest.java @@ -23,17 +23,17 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.fungibletokeninfo.FungibleTokenInfoCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.fungibletokeninfo.FungibleTokenInfoTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -67,18 +67,29 @@ class FungibleTokenInfoTranslatorTest { @Mock private ContractsConfig contractsConfig; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private FungibleTokenInfoTranslator subject; @BeforeEach void setUp() { - subject = new FungibleTokenInfoTranslator(); + subject = new FungibleTokenInfoTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesFungibleTokenInfoTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - FUNGIBLE_TOKEN_INFO, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + FUNGIBLE_TOKEN_INFO, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -92,15 +103,22 @@ void matchesFungibleTokenInfoTranslatorTestV2() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/getapproved/GetApprovedTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/getapproved/GetApprovedTranslatorTest.java index 0a28fc47cf6a..20cc50040486 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/getapproved/GetApprovedTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/getapproved/GetApprovedTranslatorTest.java @@ -24,20 +24,20 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirect; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.getapproved.GetApprovedCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.getapproved.GetApprovedTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import java.math.BigInteger; import org.apache.tuweni.bytes.Bytes; @@ -73,11 +73,16 @@ public class GetApprovedTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private GetApprovedTranslator subject; @BeforeEach void setUp() { - subject = new GetApprovedTranslator(); + subject = new GetApprovedTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -85,22 +90,40 @@ void matchesErcGetApprovedTest() { given(enhancement.nativeOperations()).willReturn(nativeOperations); given(nativeOperations.getToken(anyLong())).willReturn(FUNGIBLE_TOKEN); attempt = prepareHtsAttemptWithSelectorForRedirect( - ERC_GET_APPROVED, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + ERC_GET_APPROVED, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesHapiGetApprovedTest() { attempt = prepareHtsAttemptWithSelector( - HAPI_GET_APPROVED, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + HAPI_GET_APPROVED, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsOnIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslatorTest.java index f04ef6829ca9..f833014dc130 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantapproval/GrantApprovalTranslatorTest.java @@ -30,9 +30,8 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.UNAUTHORIZED_SPENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirect; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; @@ -40,6 +39,7 @@ import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.base.TokenType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; @@ -49,6 +49,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantapproval.ERCGrantApprovalCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantapproval.GrantApprovalDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantapproval.GrantApprovalTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import java.math.BigInteger; import org.apache.tuweni.bytes.Bytes; @@ -82,19 +83,30 @@ class GrantApprovalTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final GrantApprovalDecoder decoder = new GrantApprovalDecoder(); private GrantApprovalTranslator subject; @BeforeEach void setUp() { - subject = new GrantApprovalTranslator(decoder); + subject = new GrantApprovalTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void grantApprovalMatches() { attempt = prepareHtsAttemptWithSelector( - GRANT_APPROVAL, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + GRANT_APPROVAL, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -102,8 +114,14 @@ void ERCGrantApprovalMatches() { given(enhancement.nativeOperations()).willReturn(nativeOperations); given(nativeOperations.getToken(anyLong())).willReturn(FUNGIBLE_TOKEN); attempt = prepareHtsAttemptWithSelectorForRedirect( - ERC_GRANT_APPROVAL, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + ERC_GRANT_APPROVAL, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -116,22 +134,35 @@ void ERCGrantApprovalNFTMatches() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void grantApprovalNFTMatches() { attempt = prepareHtsAttemptWithSelector( - GRANT_APPROVAL_NFT, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + GRANT_APPROVAL_NFT, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void falseOnInvalidSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslatorTest.java index bf770ec30f67..24c57877fb0d 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/grantrevokekyc/GrantRevokeKycTranslatorTest.java @@ -20,15 +20,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantrevokekyc.GrantRevokeKycTranslator.GRANT_KYC; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantrevokekyc.GrantRevokeKycTranslator.REVOKE_KYC; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantrevokekyc.GrantRevokeKycDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.grantrevokekyc.GrantRevokeKycTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,32 +54,55 @@ class GrantRevokeKycTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final GrantRevokeKycDecoder decoder = new GrantRevokeKycDecoder(); private GrantRevokeKycTranslator subject; @BeforeEach void setUp() { - subject = new GrantRevokeKycTranslator(decoder); + subject = new GrantRevokeKycTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesGrantKycTest() { attempt = prepareHtsAttemptWithSelector( - GRANT_KYC, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + GRANT_KYC, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesRevokeKycTest() { attempt = prepareHtsAttemptWithSelector( - REVOKE_KYC, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + REVOKE_KYC, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsWithIncorrectSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isassociated/IsAssociatedTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isassociated/IsAssociatedTranslatorTest.java index 90031120546d..4c85c0818253 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isassociated/IsAssociatedTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isassociated/IsAssociatedTranslatorTest.java @@ -20,9 +20,8 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isassociated.IsAssociatedTranslator.IS_ASSOCIATED; import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirect; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; @@ -30,12 +29,14 @@ import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isassociated.IsAssociatedCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isassociated.IsAssociatedTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -64,11 +65,16 @@ class IsAssociatedTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsAssociatedTranslator translator; @BeforeEach void setUp() { - translator = new IsAssociatedTranslator(); + translator = new IsAssociatedTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -76,8 +82,14 @@ void matchesWithCorrectSelectorAndTokenRedirectReturnsTrue() { given(enhancement.nativeOperations()).willReturn(nativeOperations); given(nativeOperations.getToken(anyLong())).willReturn(FUNGIBLE_TOKEN); mockAttempt = prepareHtsAttemptWithSelectorForRedirect( - IS_ASSOCIATED, translator, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(translator.matches(mockAttempt)); + IS_ASSOCIATED, + translator, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(translator.identifyMethod(mockAttempt)).isPresent(); } @Test @@ -85,14 +97,20 @@ void matchesWithIncorrectSelectorReturnsFalse() { given(enhancement.nativeOperations()).willReturn(nativeOperations); given(nativeOperations.getToken(anyLong())).willReturn(FUNGIBLE_TOKEN); mockAttempt = prepareHtsAttemptWithSelectorForRedirect( - BURN_TOKEN_V2, translator, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(translator.matches(mockAttempt)); + BURN_TOKEN_V2, + translator, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(translator.identifyMethod(mockAttempt)).isEmpty(); } @Test void matchesWithTokenRedirectFalseReturnsFalse() { when(mockAttempt.isTokenRedirect()).thenReturn(false); - assertFalse(translator.matches(mockAttempt)); + assertThat(translator.identifyMethod(mockAttempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isfrozen/IsFrozenTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isfrozen/IsFrozenTranslatorTest.java index bcd26241eaf3..179380a2af94 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isfrozen/IsFrozenTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/isfrozen/IsFrozenTranslatorTest.java @@ -23,18 +23,18 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isfrozen.IsFrozenCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.isfrozen.IsFrozenTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -63,25 +63,42 @@ class IsFrozenTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsFrozenTranslator subject; @BeforeEach void setUp() { - subject = new IsFrozenTranslator(); + subject = new IsFrozenTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesIsFrozenTest() { attempt = prepareHtsAttemptWithSelector( - IS_FROZEN, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + IS_FROZEN, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/iskyc/IsKycTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/iskyc/IsKycTranslatorTest.java index 9d7b901b7b73..d8b19512338c 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/iskyc/IsKycTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/iskyc/IsKycTranslatorTest.java @@ -23,18 +23,18 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.fromHeadlongAddress; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.iskyc.IsKycCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.iskyc.IsKycTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -63,25 +63,42 @@ class IsKycTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsKycTranslator subject; @BeforeEach void setUp() { - subject = new IsKycTranslator(); + subject = new IsKycTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesIsKycTest() { attempt = prepareHtsAttemptWithSelector( - IS_KYC, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + IS_KYC, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/istoken/IsTokenTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/istoken/IsTokenTranslatorTest.java index e1bb35eb85c6..21b9d3ab00b5 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/istoken/IsTokenTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/istoken/IsTokenTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.istoken.IsTokenCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.istoken.IsTokenTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class IsTokenTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private IsTokenTranslator subject; @BeforeEach void setUp() { - subject = new IsTokenTranslator(); + subject = new IsTokenTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesIsTokenTest() { attempt = prepareHtsAttemptWithSelector( - IS_TOKEN, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + IS_TOKEN, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/mint/MintTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/mint/MintTranslatorTest.java index 2e7bd891de75..3556335990b6 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/mint/MintTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/mint/MintTranslatorTest.java @@ -20,15 +20,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator.MINT; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator.MINT_V2; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.mint.MintTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,33 +54,56 @@ class MintTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private MintTranslator subject; private final MintDecoder decoder = new MintDecoder(); @BeforeEach void setUp() { - subject = new MintTranslator(decoder); + subject = new MintTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesMintV1Test() { attempt = prepareHtsAttemptWithSelector( - MINT, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + MINT, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesMintV2Test() { attempt = prepareHtsAttemptWithSelector( - MINT_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + MINT_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchFailsOnIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCallTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCallTest.java index 23a9afcfee0a..fdf28de0c679 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCallTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoCallTest.java @@ -80,7 +80,7 @@ void returnsNftTokenInfoStatusForPresentToken() { FUNGIBLE_EVERYTHING_TOKEN, 2L, config, - NON_FUNGIBLE_TOKEN_INFO); + NON_FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -139,7 +139,7 @@ void returnsNftTokenInfoStatusForPresentTokenV2() { FUNGIBLE_EVERYTHING_TOKEN_V2, 2L, config, - NON_FUNGIBLE_TOKEN_INFO_V2); + NON_FUNGIBLE_TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); @@ -189,7 +189,7 @@ void returnsNftTokenInfoStatusForMissingToken() { when(ledgerConfig.id()).thenReturn(expectedLedgerId); final var subject = new NftTokenInfoCall( - gasCalculator, mockEnhancement(), false, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO); + gasCalculator, mockEnhancement(), false, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -231,8 +231,8 @@ void returnsNftTokenInfoStatusForMissingToken() { @Test void returnsNftTokenInfoStatusForMissingTokenStaticCall() { - final var subject = - new NftTokenInfoCall(gasCalculator, mockEnhancement(), true, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO); + final var subject = new NftTokenInfoCall( + gasCalculator, mockEnhancement(), true, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -243,7 +243,7 @@ void returnsNftTokenInfoStatusForMissingTokenStaticCall() { @Test void returnsNftTokenInfoStatusForMissingTokenStaticCallV2() { final var subject = new NftTokenInfoCall( - gasCalculator, mockEnhancement(), true, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO_V2); + gasCalculator, mockEnhancement(), true, null, 0L, config, NON_FUNGIBLE_TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslatorTest.java index 5516a98a808e..da5992e22dd7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/nfttokeninfo/NftTokenInfoTranslatorTest.java @@ -23,17 +23,17 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.nfttokeninfo.NftTokenInfoCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.nfttokeninfo.NftTokenInfoTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -67,11 +67,16 @@ class NftTokenInfoTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private NftTokenInfoTranslator subject; @BeforeEach void setUp() { - subject = new NftTokenInfoTranslator(); + subject = new NftTokenInfoTranslator(systemContractMethodRegistry, contractMetrics); } @Test @@ -82,8 +87,9 @@ void matchesTokenInfoTranslatorTest() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -97,15 +103,22 @@ void matchesTokenInfoTranslatorTestV2() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/pauses/PausesTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/pauses/PausesTranslatorTest.java index 123e8d40255f..b5fba05127c9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/pauses/PausesTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/pauses/PausesTranslatorTest.java @@ -20,15 +20,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.pauses.PausesTranslator.PAUSE; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.pauses.PausesTranslator.UNPAUSE; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.pauses.PausesDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.pauses.PausesTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,33 +54,56 @@ public class PausesTranslatorTest { @Mock private VerificationStrategies verificationStrategies; - private PausesDecoder decoder = new PausesDecoder(); + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + + private final PausesDecoder decoder = new PausesDecoder(); private PausesTranslator subject; @BeforeEach void setUp() { - subject = new PausesTranslator(decoder); + subject = new PausesTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesPauseTest() { attempt = prepareHtsAttemptWithSelector( - PAUSE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + PAUSE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesUnpauseTest() { attempt = prepareHtsAttemptWithSelector( - UNPAUSE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + UNPAUSE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsOnIncorrectSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslatorTest.java index 62036e369899..8154c8174f28 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/rejecttokens/RejectTokensTranslatorTest.java @@ -20,9 +20,8 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirectWithConfig; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; @@ -34,6 +33,7 @@ import com.hedera.hapi.node.transaction.TransactionBody; import com.hedera.node.app.service.contract.impl.exec.gas.DispatchType; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; @@ -43,6 +43,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.rejecttokens.RejectTokensDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.rejecttokens.RejectTokensTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -91,37 +92,36 @@ public class RejectTokensTranslatorTest { @Mock private AccountID payerId; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private RejectTokensTranslator subject; @BeforeEach void setUp() { - subject = new RejectTokensTranslator(decoder); + subject = new RejectTokensTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesHTSWithInvalidSig() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( - BurnTranslator.BURN_TOKEN_V1, + BurnTranslator.BURN_TOKEN_V1, // obvs wrong selector subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesHTSWithConfigEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(true); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( @@ -131,18 +131,13 @@ void matchesHTSWithConfigEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesHTSWithConfigDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(false); attempt = prepareHtsAttemptWithSelectorAndCustomConfig( @@ -152,18 +147,13 @@ void matchesHTSWithConfigDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesFungibleHRCWithConfigEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -174,18 +164,13 @@ void matchesFungibleHRCWithConfigEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFungibleHRCWithConfigDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -196,18 +181,13 @@ void matchesFungibleHRCWithConfigDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test void matchesNftHRCWithConfigEnabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(true); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -218,18 +198,13 @@ void matchesNftHRCWithConfigEnabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertTrue(matches); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesNftHRCWithConfigDisabled() { - // given: given(configuration.getConfigData(ContractsConfig.class)).willReturn(contractsConfig); given(contractsConfig.systemContractRejectTokensEnabled()).willReturn(false); given(enhancement.nativeOperations()).willReturn(nativeOperations); @@ -240,13 +215,9 @@ void matchesNftHRCWithConfigDisabled() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - - // when: - boolean matches = subject.matches(attempt); - - // then: - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -302,6 +273,7 @@ void callFromHtsTokenReject() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -325,6 +297,7 @@ void callFromHRCCancelFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: @@ -348,6 +321,7 @@ void callFromHRCCancelNFTAirdrop() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); // when: diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslatorTest.java index 287dd55eb857..f6a75ff8df08 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/setapproval/SetApprovalForAllTranslatorTest.java @@ -22,18 +22,19 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorForRedirect; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.HederaNativeOperations; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.setapproval.SetApprovalForAllDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.setapproval.SetApprovalForAllTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -62,20 +63,31 @@ public class SetApprovalForAllTranslatorTest { @Mock private HederaNativeOperations nativeOperations; + @Mock + private ContractMetrics contractMetrics; + private final SetApprovalForAllDecoder decoder = new SetApprovalForAllDecoder(); + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private SetApprovalForAllTranslator subject; @BeforeEach void setUp() { - subject = new SetApprovalForAllTranslator(decoder); + subject = new SetApprovalForAllTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesClassicalSelectorTest() { attempt = prepareHtsAttemptWithSelector( - SET_APPROVAL_FOR_ALL, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + SET_APPROVAL_FOR_ALL, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -88,14 +100,21 @@ void matchesERCSelectorTest() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void falseOnInvalidSelector() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslatorTest.java index f315e1cd12cd..9e89c757e5f7 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenexpiry/TokenExpiryTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenexpiry.TokenExpiryCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenexpiry.TokenExpiryTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class TokenExpiryTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenExpiryTranslator subject; @BeforeEach void setUp() { - subject = new TokenExpiryTranslator(); + subject = new TokenExpiryTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesTokenExpiryTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - TOKEN_EXPIRY, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + TOKEN_EXPIRY, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoCallTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoCallTest.java index 0799ec5d4d1c..9c6ce08c9949 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoCallTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoCallTest.java @@ -64,7 +64,7 @@ void returnsTokenInfoStatusForPresentToken() { when(ledgerConfig.id()).thenReturn(expectedLedgerId); final var subject = new TokenInfoCall( - gasCalculator, mockEnhancement(), false, FUNGIBLE_EVERYTHING_TOKEN, config, TOKEN_INFO); + gasCalculator, mockEnhancement(), false, FUNGIBLE_EVERYTHING_TOKEN, config, TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -105,7 +105,12 @@ void returnsTokenInfoStatusForPresentTokenV2() { when(ledgerConfig.id()).thenReturn(expectedLedgerId); final var subject = new TokenInfoCall( - gasCalculator, mockEnhancement(), false, FUNGIBLE_EVERYTHING_TOKEN_V2, config, TOKEN_INFO_V2); + gasCalculator, + mockEnhancement(), + false, + FUNGIBLE_EVERYTHING_TOKEN_V2, + config, + TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); @@ -147,7 +152,8 @@ void returnsTokenInfoStatusForMissingToken() { final var expectedLedgerId = com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01"); when(ledgerConfig.id()).thenReturn(expectedLedgerId); - final var subject = new TokenInfoCall(gasCalculator, mockEnhancement(), false, null, config, TOKEN_INFO); + final var subject = + new TokenInfoCall(gasCalculator, mockEnhancement(), false, null, config, TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -186,7 +192,8 @@ void returnsTokenInfoStatusForMissingTokenStaticCall() { when(config.getConfigData(LedgerConfig.class)).thenReturn(ledgerConfig); when(ledgerConfig.id()).thenReturn(com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01")); - final var subject = new TokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, TOKEN_INFO); + final var subject = + new TokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, TOKEN_INFO.function()); final var result = subject.execute().fullResult().result(); @@ -199,7 +206,8 @@ void returnsTokenInfoStatusForMissingTokenStaticCallV2() { when(config.getConfigData(LedgerConfig.class)).thenReturn(ledgerConfig); when(ledgerConfig.id()).thenReturn(com.hedera.pbj.runtime.io.buffer.Bytes.fromHex("01")); - final var subject = new TokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, TOKEN_INFO_V2); + final var subject = + new TokenInfoCall(gasCalculator, mockEnhancement(), true, null, config, TOKEN_INFO_V2.function()); final var result = subject.execute().fullResult().result(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslatorTest.java index 8f493844c995..44d380ef1b49 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokeninfo/TokenInfoTranslatorTest.java @@ -23,17 +23,17 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokeninfo.TokenInfoCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokeninfo.TokenInfoTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -67,18 +67,29 @@ class TokenInfoTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenInfoTranslator subject; @BeforeEach void setUp() { - subject = new TokenInfoTranslator(); + subject = new TokenInfoTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesTokenInfoTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - TOKEN_INFO, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + TOKEN_INFO, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -92,15 +103,23 @@ void matchesTokenInfoTranslatorTestV2() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); + ; } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenkey/TokenKeyTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenkey/TokenKeyTranslatorTest.java index daab372ef262..4c684ab83b29 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenkey/TokenKeyTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokenkey/TokenKeyTranslatorTest.java @@ -21,19 +21,19 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.base.Key; import com.hedera.hapi.node.state.token.Token; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenkey.TokenKeyCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokenkey.TokenKeyTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; import com.hedera.pbj.runtime.io.buffer.Bytes; @@ -63,25 +63,42 @@ class TokenKeyTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenKeyTranslator subject; @BeforeEach void setUp() { - subject = new TokenKeyTranslator(); + subject = new TokenKeyTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesTokenKeyTranslatorTest() { attempt = prepareHtsAttemptWithSelector( - TOKEN_KEY, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + TOKEN_KEY, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokentype/TokenTypeTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokentype/TokenTypeTranslatorTest.java index f32ca405fa27..416c5ce8c970 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokentype/TokenTypeTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/tokentype/TokenTypeTranslatorTest.java @@ -21,17 +21,17 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokentype.TokenTypeCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.tokentype.TokenTypeTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; @@ -57,25 +57,42 @@ class TokenTypeTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private TokenTypeTranslator subject; @BeforeEach void setUp() { - subject = new TokenTypeTranslator(); + subject = new TokenTypeTranslator(systemContractMethodRegistry, contractMetrics); } @Test void matchesTokenTypeTest() { attempt = prepareHtsAttemptWithSelector( - TOKEN_TYPE, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + TOKEN_TYPE, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesFailsIfIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/transfer/ClassicTransfersTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/transfer/ClassicTransfersTranslatorTest.java index 5686a0a12588..15397c2ece36 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/transfer/ClassicTransfersTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/transfer/ClassicTransfersTranslatorTest.java @@ -26,6 +26,7 @@ import static org.mockito.BDDMockito.given; import com.hedera.hapi.node.base.AccountID; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.common.CallTranslator; @@ -34,6 +35,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.ClassicTransfersCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.ClassicTransfersDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.transfer.ClassicTransfersTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.swirlds.common.utility.CommonUtils; import java.lang.reflect.Field; @@ -63,13 +65,19 @@ class ClassicTransfersTranslatorTest extends CallTestBase { @Mock private VerificationStrategy strategy; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private ClassicTransfersTranslator subject; private List> callTranslators; @BeforeEach void setUp() { - callTranslators = List.of(new ClassicTransfersTranslator(classicTransfersDecoder)); + callTranslators = List.of( + new ClassicTransfersTranslator(classicTransfersDecoder, systemContractMethodRegistry, contractMetrics)); } @Test @@ -81,7 +89,8 @@ void returnsAttemptWithAuthorizingId() throws NoSuchFieldException, IllegalAcces NON_SYSTEM_LONG_ZERO_ADDRESS, true, nativeOperations)) .willReturn(strategy); - subject = new ClassicTransfersTranslator(classicTransfersDecoder); + subject = + new ClassicTransfersTranslator(classicTransfersDecoder, systemContractMethodRegistry, contractMetrics); final var call = subject.callFrom(givenV2SubjectWithV2Enabled(ABI_ID_TRANSFER_TOKEN)); Field senderIdField = ClassicTransfersCall.class.getDeclaredField("senderId"); senderIdField.setAccessible(true); @@ -97,7 +106,8 @@ void returnsAttemptWithSenderId() throws NoSuchFieldException, IllegalAccessExce NON_SYSTEM_LONG_ZERO_ADDRESS, true, nativeOperations)) .willReturn(strategy); - subject = new ClassicTransfersTranslator(classicTransfersDecoder); + subject = + new ClassicTransfersTranslator(classicTransfersDecoder, systemContractMethodRegistry, contractMetrics); final var call = subject.callFrom(givenV2SubjectWithV2Enabled(ABI_ID_CRYPTO_TRANSFER_V2)); Field senderIdField = ClassicTransfersCall.class.getDeclaredField("senderId"); senderIdField.setAccessible(true); @@ -119,6 +129,7 @@ private HtsCallAttempt givenV2SubjectWithV2Enabled(final String functionSelector verificationStrategies, gasCalculator, callTranslators, + systemContractMethodRegistry, false); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateExpiryTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateExpiryTranslatorTest.java index 0221387dd9c0..37473373ed63 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateExpiryTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateExpiryTranslatorTest.java @@ -24,13 +24,12 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.OWNER_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -38,6 +37,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateExpiryTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import java.time.Instant; import org.apache.tuweni.bytes.Bytes; @@ -67,6 +67,11 @@ class UpdateExpiryTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private UpdateExpiryTranslator subject; private final UpdateDecoder decoder = new UpdateDecoder(); @@ -77,7 +82,7 @@ class UpdateExpiryTranslatorTest { @BeforeEach void setUp() { - subject = new UpdateExpiryTranslator(decoder); + subject = new UpdateExpiryTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -88,8 +93,9 @@ void matchesUpdateExpiryV1Test() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -100,8 +106,9 @@ void matchesUpdateExpiryV2Test() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -112,8 +119,9 @@ void matchesFailsIfIncorrectSelectorTest() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateKeysTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateKeysTranslatorTest.java index ec187f0ae306..4f1380eac97f 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateKeysTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateKeysTranslatorTest.java @@ -17,16 +17,17 @@ package com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.hts.update; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateKeysTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -51,13 +52,18 @@ class UpdateKeysTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private UpdateKeysTranslator subject; private final UpdateDecoder decoder = new UpdateDecoder(); @BeforeEach void setUp() { - subject = new UpdateKeysTranslator(decoder); + subject = new UpdateKeysTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -68,8 +74,9 @@ void matchesUpdateKeysTest() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -80,7 +87,8 @@ void matchesIncorrectSelectorFailsTest() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslatorTest.java index f14f58436c71..d7405c45aee6 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateNFTsMetadataTranslatorTest.java @@ -19,22 +19,24 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.NON_FUNGIBLE_TOKEN_HEADLONG_ADDRESS; import static com.hedera.node.app.service.contract.impl.test.TestHelpers.NON_SYSTEM_ACCOUNT_ID; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.DispatchForResponseCodeHtsCall; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateNFTsMetadataTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; import com.swirlds.config.api.Configuration; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -60,29 +62,30 @@ class UpdateNFTsMetadataTranslatorTest { @Mock private VerificationStrategy verificationStrategy; + @Mock + private ContractMetrics contractMetrics; + private UpdateNFTsMetadataTranslator subject; private final UpdateDecoder decoder = new UpdateDecoder(); @BeforeEach void setUp() { - subject = new UpdateNFTsMetadataTranslator(decoder); + subject = new UpdateNFTsMetadataTranslator(decoder, new SystemContractMethodRegistry(), contractMetrics); } @Test void matchesUpdateNFTsMetadataTest() { given(attempt.configuration()).willReturn(getTestConfiguration(true)); - given(attempt.isSelector(UpdateNFTsMetadataTranslator.UPDATE_NFTs_METADATA)) - .willReturn(true); - final var matches = subject.matches(attempt); - assertThat(matches).isTrue(); + given(attempt.isMethod(UpdateNFTsMetadataTranslator.UPDATE_NFTs_METADATA)) + .willReturn(Optional.of(UpdateNFTsMetadataTranslator.UPDATE_NFTs_METADATA)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void doesNotMatchUpdateNFTsMetadataWhenDisabled() { given(attempt.configuration()).willReturn(getTestConfiguration(false)); - var matches = subject.matches(attempt); - assertFalse(matches); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateTranslatorTest.java index 13d92969da66..ab4280bde348 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/update/UpdateTranslatorTest.java @@ -36,8 +36,6 @@ import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.lenient; @@ -46,6 +44,7 @@ import com.esaulpaugh.headlong.abi.Tuple; import com.hedera.hapi.node.token.TokenUpdateTransactionBody; import com.hedera.hapi.node.transaction.TransactionBody; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -54,6 +53,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.freeze.FreezeUnfreezeTranslator; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.update.UpdateTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.app.service.token.ReadableAccountStore; @@ -96,6 +96,11 @@ class UpdateTranslatorTest extends CallTestBase { @Mock Configuration configuration; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private UpdateTranslator subject; private final UpdateDecoder decoder = new UpdateDecoder(); @@ -115,7 +120,7 @@ class UpdateTranslatorTest extends CallTestBase { @BeforeEach void setUp() { - subject = new UpdateTranslator(decoder); + subject = new UpdateTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -187,8 +192,9 @@ void matchesUpdateV1Test() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -199,8 +205,9 @@ void matchesUpdateV2Test() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -211,8 +218,9 @@ void matchesUpdateV3Test() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertTrue(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -226,8 +234,9 @@ void matchesUpdateMetadataTest() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -238,8 +247,9 @@ void matchesFailsOnIncorrectSelector() { enhancement, addressIdConverter, verificationStrategies, - gasCalculator); - assertFalse(subject.matches(attempt)); + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslatorTest.java index d658d3081494..76cdd3e274b4 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/updatetokencustomfees/UpdateTokenCustomFeesTranslatorTest.java @@ -26,14 +26,13 @@ import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SENDER_ID; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelectorAndCustomConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.lenient; import com.esaulpaugh.headlong.abi.Address; import com.esaulpaugh.headlong.abi.Tuple; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategy; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; @@ -41,6 +40,7 @@ import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.updatetokencustomfees.UpdateTokenCustomFeesDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.updatetokencustomfees.UpdateTokenCustomFeesTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.common.CallTestBase; import com.hedera.node.config.data.ContractsConfig; @@ -80,13 +80,18 @@ class UpdateTokenCustomFeesTranslatorTest extends CallTestBase { @Mock private VerificationStrategies verificationStrategies; + @Mock + private ContractMetrics contractMetrics; + + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final UpdateTokenCustomFeesDecoder decoder = new UpdateTokenCustomFeesDecoder(); private UpdateTokenCustomFeesTranslator subject; @BeforeEach void setUp() { - subject = new UpdateTokenCustomFeesTranslator(decoder); + subject = new UpdateTokenCustomFeesTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test @@ -100,8 +105,9 @@ void matchesIsTrueWhenSelectorForFungibleIsCorrect() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -115,8 +121,9 @@ void matchesIsTrueWhenSelectorForNFTIsCorrect() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertTrue(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test @@ -124,7 +131,7 @@ void matchesFailsIfFeatureFlagDisabled() { // given: setConfiguration(false); // expect: - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test @@ -138,8 +145,9 @@ void matchesIsFalseWhenSelectorsAreIncorrect() { addressIdConverter, verificationStrategies, gasCalculator, + systemContractMethodRegistry, configuration); - assertFalse(subject.matches(attempt)); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/wipe/WipeTranslatorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/wipe/WipeTranslatorTest.java index fa616351155a..0051d7baa7b2 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/wipe/WipeTranslatorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/systemcontracts/hts/wipe/WipeTranslatorTest.java @@ -19,15 +19,16 @@ import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.burn.BurnTranslator.BURN_TOKEN_V2; import static com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.wipe.WipeTranslator.WIPE_FUNGIBLE_V1; import static com.hedera.node.app.service.contract.impl.test.exec.systemcontracts.CallAttemptHelpers.prepareHtsAttemptWithSelector; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.scope.VerificationStrategies; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.AddressIdConverter; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.HtsCallAttempt; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.wipe.WipeDecoder; import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.wipe.WipeTranslator; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater.Enhancement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,40 +54,69 @@ public class WipeTranslatorTest { @Mock private VerificationStrategies verificationStrategies; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + + @Mock + private ContractMetrics contractMetrics; + private final WipeDecoder decoder = new WipeDecoder(); private WipeTranslator subject; @BeforeEach void setup() { - subject = new WipeTranslator(decoder); + subject = new WipeTranslator(decoder, systemContractMethodRegistry, contractMetrics); } @Test void matchesWipeFungibleV1Test() { attempt = prepareHtsAttemptWithSelector( - WIPE_FUNGIBLE_V1, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + WIPE_FUNGIBLE_V1, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesWipeFungibleV2Test() { attempt = prepareHtsAttemptWithSelector( - WIPE_FUNGIBLE_V1, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + WIPE_FUNGIBLE_V1, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchesWipeNftTest() { attempt = prepareHtsAttemptWithSelector( - WIPE_FUNGIBLE_V1, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertTrue(subject.matches(attempt)); + WIPE_FUNGIBLE_V1, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isPresent(); } @Test void matchFailsOnIncorrectSelectorTest() { attempt = prepareHtsAttemptWithSelector( - BURN_TOKEN_V2, subject, enhancement, addressIdConverter, verificationStrategies, gasCalculator); - assertFalse(subject.matches(attempt)); + BURN_TOKEN_V2, + subject, + enhancement, + addressIdConverter, + verificationStrategies, + gasCalculator, + systemContractMethodRegistry); + assertThat(subject.identifyMethod(attempt)).isEmpty(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/utils/SystemContractMethodRegistryTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/utils/SystemContractMethodRegistryTest.java new file mode 100644 index 000000000000..f7ea611e1bf5 --- /dev/null +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/utils/SystemContractMethodRegistryTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2024 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.contract.impl.test.exec.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.esaulpaugh.headlong.abi.Function; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.getevmaddressalias.EvmAddressAliasTranslator; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.hbarapprove.HbarApproveTranslator; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.has.isvalidalias.IsValidAliasTranslator; +import com.hedera.node.app.service.contract.impl.exec.systemcontracts.hts.ReturnTypes; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.CallVia; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.SystemContract; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethod.Variant; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; +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) +public class SystemContractMethodRegistryTest { + + @Mock + ContractMetrics contractMetrics; + + @Test + void testMethodCreationHappyPath() { + + final var signature = new Function("collectReward(string)", ReturnTypes.ADDRESS); + final var subject = SystemContractMethod.declare( + signature.getCanonicalSignature(), + signature.getOutputs().toString()) + .withContract(SystemContract.EXCHANGE) + .withVia(CallVia.DIRECT); + + assertThat(subject.methodName()).isEqualTo("collectReward"); + assertThat(subject.qualifiedMethodName()).isEqualTo("EXCHANGE.collectReward"); + assertThat(subject.signature()).isEqualTo("collectReward(string)"); + assertThat(subject.signatureWithReturn()).isEqualTo("collectReward(string):(address)"); + assertThat(subject.selectorLong()).isEqualTo(0x3cbf0049L); + assertThat(subject.selectorHex()).isEqualTo("3cbf0049"); + } + + @Test + void testMethodCreationVariations() { + + final var signature = new Function("collectReward(string)", ReturnTypes.ADDRESS); + + // Proxy + final var subjectProxy = SystemContractMethod.declare( + signature.getCanonicalSignature(), + signature.getOutputs().toString()) + .withContract(SystemContract.EXCHANGE) + .withVia(CallVia.PROXY); + assertThat(subjectProxy.qualifiedMethodName()).isEqualTo("EXCHANGE(PROXY).collectReward"); + + // Variant method name + final var subjectOverrideName = SystemContractMethod.declare( + signature.getCanonicalSignature(), + signature.getOutputs().toString()) + .withContract(SystemContract.EXCHANGE) + .withVariant(Variant.NFT); + assertThat(subjectOverrideName.qualifiedMethodName()).isEqualTo("EXCHANGE.collectReward_NFT"); + assertThat(subjectOverrideName.signature()).isEqualTo("collectReward(string)"); + assertThat(subjectOverrideName.selectorLong()).isEqualTo(0x3cbf0049L); + } + + @Test + void testHappyMethodRegistrations() { + + final var subject = new SystemContractMethodRegistry(); + + // Add some registrations by simply creating instances of classes known to register methods + + final var t1 = new IsValidAliasTranslator(subject, contractMetrics); + final var t2 = new HbarApproveTranslator(subject, contractMetrics); + final var t3 = new EvmAddressAliasTranslator(subject, contractMetrics); + + // Test expected methods are registered (test data is known from looking at the classes involved) + + // HAS(PROXY).hbarApprove: 0x86aff07c - hbarApprove(address,int256):(int64) + // HAS.getEvmAddressAlias: 0xdea3d081 - getEvmAddressAlias(address):(int64,address) + // HAS.hbarApprove: 0xa0918464 - hbarApprove(address,address,int256):(int64) + // HAS.isValidAlias: 0x308ef301 - isValidAlias(address):(bool) + + final var actualAllQualifiedMethods = subject.allQualifiedMethods(); + assertThat(actualAllQualifiedMethods) + .hasSize(4) + .containsExactlyInAnyOrder( + "HAS.isValidAlias", "HAS.getEvmAddressAlias", "HAS.hbarApprove", "HAS(PROXY).hbarApprove"); + + final var actualAllSignatures = subject.allSignatures(); + assertThat(actualAllSignatures) + .hasSize(4) + .containsExactlyInAnyOrder( + "getEvmAddressAlias(address)", + "hbarApprove(address,address,int256)", + "hbarApprove(address,int256)", + "isValidAlias(address)"); + + final var actualAllSignaturesWithReturns = subject.allSignaturesWithReturns(); + assertThat(actualAllSignaturesWithReturns) + .hasSize(4) + .containsExactlyInAnyOrder( + "getEvmAddressAlias(address):(int64,address)", + "hbarApprove(address,address,int256):(int64)", + "hbarApprove(address,int256):(int64)", + "isValidAlias(address):(bool)"); + } + + @Test + void testDuplicateMethodRegistrationRegistersOnlyOneCopy() { + + final var subject = new SystemContractMethodRegistry(); + + // Add some registrations twice - this might happen if a `FooTranslator` isn't marked `@Singleton` + final var t1 = new IsValidAliasTranslator(subject, contractMetrics); + final var t2 = new IsValidAliasTranslator(subject, contractMetrics); + + // Test only one method is registered + + final var actualAllQualifiedMethods = subject.allQualifiedMethods(); + assertThat(actualAllQualifiedMethods).hasSize(1).containsExactly("HAS.isValidAlias"); + + final var actualAllSignatures = subject.allSignatures(); + assertThat(actualAllSignatures).hasSize(1).containsExactly("isValidAlias(address)"); + + final var actualAllSignaturesWithReturns = subject.allSignaturesWithReturns(); + assertThat(actualAllSignaturesWithReturns).hasSize(1).containsExactly("isValidAlias(address):(bool)"); + } +} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallHandlerTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallHandlerTest.java index 5d22d1890543..9070a3fb8587 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallHandlerTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallHandlerTest.java @@ -37,6 +37,7 @@ import com.hedera.node.app.service.contract.impl.exec.ContextTransactionProcessor; import com.hedera.node.app.service.contract.impl.exec.TransactionComponent; import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.handlers.ContractCallHandler; import com.hedera.node.app.service.contract.impl.records.ContractCallStreamBuilder; import com.hedera.node.app.service.contract.impl.state.RootProxyWorldUpdater; @@ -92,14 +93,17 @@ class ContractCallHandlerTest extends ContractHandlerTestBase { @Mock private ContractsConfig contractsConfig; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final Metrics metrics = new NoOpMetrics(); - private final ContractMetrics contractMetrics = new ContractMetrics(() -> metrics, () -> contractsConfig); + private final ContractMetrics contractMetrics = + new ContractMetrics(() -> metrics, () -> contractsConfig, systemContractMethodRegistry); private ContractCallHandler subject; @BeforeEach void setUp() { - contractMetrics.createContractMetrics(); + contractMetrics.createContractPrimaryMetrics(); given(contractServiceComponent.contractMetrics()).willReturn(contractMetrics); subject = new ContractCallHandler(() -> factory, gasCalculator, contractServiceComponent); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallLocalHandlerTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallLocalHandlerTest.java index 84d6d535d7ae..d2e5fd8afdbf 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallLocalHandlerTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCallLocalHandlerTest.java @@ -40,9 +40,11 @@ import com.hedera.hapi.node.transaction.Query; import com.hedera.node.app.hapi.utils.fee.FeeBuilder; import com.hedera.node.app.hapi.utils.fee.SigValueObj; +import com.hedera.node.app.service.contract.impl.ContractServiceComponent; import com.hedera.node.app.service.contract.impl.exec.CallOutcome; import com.hedera.node.app.service.contract.impl.exec.ContextQueryProcessor; import com.hedera.node.app.service.contract.impl.exec.QueryComponent; +import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.handlers.ContractCallLocalHandler; import com.hedera.node.app.service.token.ReadableAccountStore; import com.hedera.node.app.service.token.ReadableTokenStore; @@ -61,6 +63,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; +import org.mockito.Mock.Strictness; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) @@ -120,9 +123,16 @@ class ContractCallLocalHandlerTest { private ContractCallLocalHandler subject; + @Mock(strictness = Strictness.LENIENT) + private ContractServiceComponent contractServiceComponent; + + @Mock + private ContractMetrics contractMetrics; + @BeforeEach void setUp() { - subject = new ContractCallLocalHandler(() -> factory, gasCalculator, instantSource); + given(contractServiceComponent.contractMetrics()).willReturn(contractMetrics); + subject = new ContractCallLocalHandler(() -> factory, gasCalculator, instantSource, contractServiceComponent); } @Test diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCreateHandlerTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCreateHandlerTest.java index 75b78bdc1136..2441a5619770 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCreateHandlerTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/ContractCreateHandlerTest.java @@ -41,6 +41,7 @@ import com.hedera.node.app.service.contract.impl.exec.ContextTransactionProcessor; import com.hedera.node.app.service.contract.impl.exec.TransactionComponent; import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.handlers.ContractCreateHandler; import com.hedera.node.app.service.contract.impl.records.ContractCreateStreamBuilder; import com.hedera.node.app.service.contract.impl.state.RootProxyWorldUpdater; @@ -98,14 +99,17 @@ class ContractCreateHandlerTest extends ContractHandlerTestBase { @Mock private ContractsConfig contractsConfig; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final Metrics metrics = new NoOpMetrics(); - private final ContractMetrics contractMetrics = new ContractMetrics(() -> metrics, () -> contractsConfig); + private final ContractMetrics contractMetrics = + new ContractMetrics(() -> metrics, () -> contractsConfig, systemContractMethodRegistry); private ContractCreateHandler subject; @BeforeEach void setUp() { - contractMetrics.createContractMetrics(); + contractMetrics.createContractPrimaryMetrics(); given(contractServiceComponent.contractMetrics()).willReturn(contractMetrics); subject = new ContractCreateHandler(() -> factory, gasCalculator, contractServiceComponent); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/EthereumTransactionHandlerTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/EthereumTransactionHandlerTest.java index c87e79f5ed42..bd77278249c0 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/EthereumTransactionHandlerTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/handlers/EthereumTransactionHandlerTest.java @@ -50,6 +50,7 @@ import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; import com.hedera.node.app.service.contract.impl.exec.metrics.ContractMetrics; import com.hedera.node.app.service.contract.impl.exec.tracers.EvmActionTracer; +import com.hedera.node.app.service.contract.impl.exec.utils.SystemContractMethodRegistry; import com.hedera.node.app.service.contract.impl.handlers.EthereumTransactionHandler; import com.hedera.node.app.service.contract.impl.hevm.HederaEvmContext; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; @@ -165,12 +166,15 @@ class EthereumTransactionHandlerTest { @Mock private ContractsConfig contractsConfig; + private final SystemContractMethodRegistry systemContractMethodRegistry = new SystemContractMethodRegistry(); + private final Metrics metrics = new NoOpMetrics(); - private final ContractMetrics contractMetrics = new ContractMetrics(() -> metrics, () -> contractsConfig); + private final ContractMetrics contractMetrics = + new ContractMetrics(() -> metrics, () -> contractsConfig, systemContractMethodRegistry); @BeforeEach void setUp() { - contractMetrics.createContractMetrics(); + contractMetrics.createContractPrimaryMetrics(); given(contractServiceComponent.contractMetrics()).willReturn(contractMetrics); subject = new EthereumTransactionHandler( ethereumSignatures, callDataHydration, () -> factory, gasCalculator, contractServiceComponent);