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);