From 7a4616bf840053c73a0713600bd50a09d6238b1b Mon Sep 17 00:00:00 2001 From: lukelee-sl <109538178+lukelee-sl@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:18:29 -0700 Subject: [PATCH] refactor: remove AbortException (#15004) Signed-off-by: lukelee-sl --- .../node/config/data/ContractsConfig.java | 4 +- .../exec/ContextTransactionProcessor.java | 74 +++++++------- .../impl/exec/TransactionProcessor.java | 28 +----- .../impl/exec/failure/AbortException.java | 99 ------------------- .../exec/v046/Version046FeatureFlags.java | 2 +- .../impl/hevm/HederaEvmTransaction.java | 19 ++++ .../exec/ContextTransactionProcessorTest.java | 70 ++++++++++++- .../test/exec/TransactionProcessorTest.java | 22 +++-- 8 files changed, 146 insertions(+), 172 deletions(-) delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/AbortException.java diff --git a/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/ContractsConfig.java b/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/ContractsConfig.java index 62c9dedae00a..032f68ffac72 100644 --- a/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/ContractsConfig.java +++ b/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/ContractsConfig.java @@ -87,8 +87,8 @@ public record ContractsConfig( boolean evmVersionDynamic, @ConfigProperty(value = "evm.allowCallsToNonContractAccounts", defaultValue = "true") @NetworkProperty boolean evmAllowCallsToNonContractAccounts, - @ConfigProperty(value = "evm.chargeGasOnPreEvmException", defaultValue = "true") @NetworkProperty - boolean chargeGasOnPreEvmException, + @ConfigProperty(value = "evm.chargeGasOnEvmHandleException", defaultValue = "true") @NetworkProperty + boolean chargeGasOnEvmHandleException, @ConfigProperty(value = "evm.nonExtantContractsFail", defaultValue = "0") @NetworkProperty Set evmNonExtantContractsFail, @ConfigProperty(value = "evm.version", defaultValue = "v0.50") @NetworkProperty String evmVersion) {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ContextTransactionProcessor.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ContextTransactionProcessor.java index 49a56f2cbed6..b43d83f4de49 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ContextTransactionProcessor.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ContextTransactionProcessor.java @@ -19,11 +19,11 @@ import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_CONTRACT_ID; import static java.util.Objects.requireNonNull; +import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.ContractID; import com.hedera.hapi.streams.ContractBytecode; import com.hedera.node.app.hapi.utils.ethereum.EthTxData; import com.hedera.node.app.service.contract.impl.annotations.TransactionScope; -import com.hedera.node.app.service.contract.impl.exec.failure.AbortException; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; import com.hedera.node.app.service.contract.impl.exec.tracers.AddOnEvmActionTracer; import com.hedera.node.app.service.contract.impl.exec.tracers.EvmActionTracer; @@ -33,6 +33,7 @@ import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.hevm.HydratedEthTxData; import com.hedera.node.app.service.contract.impl.infra.HevmTransactionFactory; +import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; import com.hedera.node.app.service.contract.impl.state.RootProxyWorldUpdater; import com.hedera.node.app.spi.workflows.HandleContext; import com.hedera.node.app.spi.workflows.HandleException; @@ -109,8 +110,12 @@ public CallOutcome call() { // if an exception occurs during a ContractCall, charge fees to the sender and return a CallOutcome reflecting // the error. final var hevmTransaction = safeCreateHevmTransaction(); - if (hevmTransaction.isException() && contractsConfig.chargeGasOnPreEvmException()) { - return chargeFeesAndReturnOutcome(hevmTransaction); + if (hevmTransaction.isException()) { + return maybeChargeFeesAndReturnOutcome( + hevmTransaction, + context.body().transactionIDOrThrow().accountIDOrThrow(), + null, + contractsConfig.chargeGasOnEvmHandleException()); } // Process the transaction and return its outcome @@ -135,30 +140,15 @@ public CallOutcome call() { } return CallOutcome.fromResultsWithMaybeSidecars( result.asProtoResultOf(ethTxDataIfApplicable(), rootProxyWorldUpdater), result); - } catch (AbortException e) { - if (e.isChargeable() && contractsConfig.chargeGasOnPreEvmException()) { - gasCharging.chargeGasForAbortedTransaction( - requireNonNull(e.senderId()), hederaEvmContext, rootProxyWorldUpdater, hevmTransaction); - } - // Commit any HAPI fees that were charged before aborting - rootProxyWorldUpdater.commit(); - - ContractID recipientId = null; - if (!INVALID_CONTRACT_ID.equals(e.getStatus())) { - recipientId = hevmTransaction.contractId(); - } - - var result = HederaEvmTransactionResult.fromAborted(e.senderId(), recipientId, e.getStatus()); - - if (context.body().hasEthereumTransaction()) { - final var sender = rootProxyWorldUpdater.getHederaAccount(e.senderId()); - if (sender != null) { - result = result.withSignerNonce(sender.getNonce()); - } - } - - return CallOutcome.fromResultsWithoutSidecars( - result.asProtoResultOf(ethTxDataIfApplicable(), rootProxyWorldUpdater), result); + } catch (HandleException e) { + final var sender = rootProxyWorldUpdater.getHederaAccount(hevmTransaction.senderId()); + final var senderId = sender != null ? sender.hederaId() : hevmTransaction.senderId(); + + return maybeChargeFeesAndReturnOutcome( + hevmTransaction.withException(e), + senderId, + sender, + hevmTransaction.isContractCall() && contractsConfig.chargeGasOnEvmHandleException()); } } @@ -171,16 +161,28 @@ private HederaEvmTransaction safeCreateHevmTransaction() { } } - private CallOutcome chargeFeesAndReturnOutcome(@NonNull final HederaEvmTransaction hevmTransaction) { - // If there was an exception while creating the HederaEvmTransaction and the transaction is a ContractCall - // charge fees to the sender and return a CallOutcome reflecting the error. - final var senderId = context.body().transactionIDOrThrow().accountIDOrThrow(); - gasCharging.chargeGasForAbortedTransaction(senderId, hederaEvmContext, rootProxyWorldUpdater, hevmTransaction); + private CallOutcome maybeChargeFeesAndReturnOutcome( + @NonNull final HederaEvmTransaction hevmTransaction, + @NonNull final AccountID senderId, + @Nullable final HederaEvmAccount sender, + final boolean chargeGas) { + final var status = requireNonNull(hevmTransaction.exception()).getStatus(); + if (chargeGas) { + gasCharging.chargeGasForAbortedTransaction( + senderId, hederaEvmContext, rootProxyWorldUpdater, hevmTransaction); + } rootProxyWorldUpdater.commit(); - final var result = HederaEvmTransactionResult.fromAborted( - senderId, - hevmTransaction.contractId(), - hevmTransaction.exception().getStatus()); + ContractID recipientId = null; + if (!INVALID_CONTRACT_ID.equals(status)) { + recipientId = hevmTransaction.contractId(); + } + + var result = HederaEvmTransactionResult.fromAborted(senderId, recipientId, status); + + if (context.body().hasEthereumTransaction() && sender != null) { + result = result.withSignerNonce(sender.getNonce()); + } + return CallOutcome.fromResultsWithoutSidecars( result.asProtoResultOf(ethTxDataIfApplicable(), rootProxyWorldUpdater), result); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionProcessor.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionProcessor.java index 51e9a508d60a..aa2b3cac65e9 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionProcessor.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionProcessor.java @@ -19,7 +19,6 @@ import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_ACCOUNT_ID; import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_CONTRACT_ID; import static com.hedera.hapi.node.base.ResponseCodeEnum.WRONG_NONCE; -import static com.hedera.node.app.service.contract.impl.exec.failure.AbortException.validateTrueOrAbort; import static com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionResult.resourceExhaustionFrom; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.contractIDToBesuAddress; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.isEvmAddress; @@ -31,7 +30,6 @@ import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.hapi.node.contract.ContractCreateTransactionBody; -import com.hedera.node.app.service.contract.impl.exec.failure.AbortException; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; import com.hedera.node.app.service.contract.impl.exec.utils.FrameBuilder; @@ -40,7 +38,6 @@ import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionResult; import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.ResourceExhaustedException; import com.hedera.node.config.data.ContractsConfig; import com.swirlds.config.api.Configuration; @@ -113,7 +110,6 @@ public FeatureFlags featureFlags() { * @param tracer the tracer to use * @param config the node configuration * @return the result of running the transaction to completion - * @throws AbortException if processing failed before initiating the EVM transaction */ public HederaEvmTransactionResult processTransaction( @NonNull final HederaEvmTransaction transaction, @@ -123,14 +119,7 @@ public HederaEvmTransactionResult processTransaction( @NonNull final ActionSidecarContentTracer tracer, @NonNull final Configuration config) { final var parties = computeInvolvedPartiesOrAbort(transaction, updater, config); - try { - return processTransactionWithParties( - transaction, updater, feesOnlyUpdater, context, tracer, config, parties); - } catch (HandleException e) { - final var sender = updater.getHederaAccount(transaction.senderId()); - final var senderId = sender != null ? sender.hederaId() : transaction.senderId(); - throw new AbortException(e.getStatus(), senderId); - } + return processTransactionWithParties(transaction, updater, feesOnlyUpdater, context, tracer, config, parties); } private HederaEvmTransactionResult processTransactionWithParties( @@ -175,13 +164,7 @@ private InvolvedParties computeInvolvedPartiesOrAbort( @NonNull final HederaEvmTransaction transaction, @NonNull final HederaWorldUpdater updater, @NonNull final Configuration config) { - try { - return computeInvolvedParties(transaction, updater, config); - } catch (AbortException e) { - throw e; - } catch (HandleException e) { - throw new AbortException(e.getStatus(), transaction.senderId(), null, true); - } + return computeInvolvedParties(transaction, updater, config); } private HederaEvmTransactionResult safeCommit( @@ -243,12 +226,11 @@ private InvolvedParties computeInvolvedParties( @NonNull final HederaWorldUpdater updater, @NonNull final Configuration config) { final var sender = updater.getHederaAccount(transaction.senderId()); - validateTrueOrAbort(sender != null, INVALID_ACCOUNT_ID, transaction.senderId()); - final var senderId = sender.hederaId(); + validateTrue(sender != null, INVALID_ACCOUNT_ID); HederaEvmAccount relayer = null; if (transaction.isEthereumTransaction()) { relayer = updater.getHederaAccount(requireNonNull(transaction.relayerId())); - validateTrueOrAbort(relayer != null, INVALID_ACCOUNT_ID, senderId); + validateTrue(relayer != null, INVALID_ACCOUNT_ID); } final InvolvedParties parties; if (transaction.isCreate()) { @@ -270,7 +252,7 @@ private InvolvedParties computeInvolvedParties( } } if (transaction.isEthereumTransaction()) { - validateTrueOrAbort(transaction.nonce() == parties.sender().getNonce(), WRONG_NONCE, senderId); + validateTrue(transaction.nonce() == parties.sender().getNonce(), WRONG_NONCE); } return parties; } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/AbortException.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/AbortException.java deleted file mode 100644 index 7186be142f3d..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/AbortException.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2023-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.failure; - -import static java.util.Objects.requireNonNull; - -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ResponseCodeEnum; -import com.hedera.node.app.spi.workflows.HandleException; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -/** - * An exception thrown when a transaction is aborted before entering the EVM. - * - *

Includes the effective Hedera id of the sender. - */ -public class AbortException extends HandleException { - private final AccountID senderId; - - @Nullable - private final AccountID relayerId; - // Whether gas can still be charged for the transaction - private final boolean isChargeable; - - public AbortException(@NonNull final ResponseCodeEnum status, @NonNull final AccountID senderId) { - super(status); - this.senderId = requireNonNull(senderId); - this.relayerId = null; - this.isChargeable = false; - } - - public AbortException( - @NonNull final ResponseCodeEnum status, - @NonNull final AccountID senderId, - @Nullable final AccountID relayerId, - final boolean isChargeable) { - super(status); - this.senderId = requireNonNull(senderId); - this.relayerId = relayerId; - this.isChargeable = isChargeable; - } - - /** - * Returns the effective Hedera id of the sender. - * - * @return the effective Hedera id of the sender - */ - public AccountID senderId() { - return senderId; - } - - /** - * Returns whether the transaction can still be charged for gas. - * - * @return whether the transaction can still be charged for gas. - */ - public boolean isChargeable() { - return isChargeable; - } - - /** - * Returns the relayer id. - * - * @return the relayer id. - */ - @Nullable - public AccountID relayerId() { - return relayerId; - } - - /** - * Throws an {@code AbortException} if the given flag is {@code false}. - * - * @param flag the flag to check - * @param status the status to use if the flag is {@code false} - * @param senderId the effective Hedera id of the sender - */ - public static void validateTrueOrAbort( - final boolean flag, @NonNull final ResponseCodeEnum status, @NonNull final AccountID senderId) { - if (!flag) { - throw new AbortException(status, senderId); - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v046/Version046FeatureFlags.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v046/Version046FeatureFlags.java index c961bf7e5cfc..20af04cf60ce 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v046/Version046FeatureFlags.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v046/Version046FeatureFlags.java @@ -41,6 +41,6 @@ public boolean isAllowCallsToNonContractAccountsEnabled( @Override public boolean isChargeGasOnPreEvmException(@NonNull Configuration config) { - return config.getConfigData(ContractsConfig.class).chargeGasOnPreEvmException(); + return config.getConfigData(ContractsConfig.class).chargeGasOnEvmHandleException(); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java index 596f57240845..56964caa7407 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java @@ -127,4 +127,23 @@ public long offeredGasCost() { public boolean requiresFullRelayerAllowance() { return offeredGasPrice == 0L; } + + /** + * @return a copy of this transaction with the given {@code exception} + */ + public HederaEvmTransaction withException(@NonNull final HandleException exception) { + return new HederaEvmTransaction( + this.senderId, + this.relayerId, + this.contractId, + this.nonce, + this.payload, + this.chainId, + this.value, + this.gasLimit, + this.offeredGasPrice, + this.maxGasAllowance, + this.hapiCreation, + exception); + } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/ContextTransactionProcessorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/ContextTransactionProcessorTest.java index cb4f3f553772..0f5ec2a45555 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/ContextTransactionProcessorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/ContextTransactionProcessorTest.java @@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import com.hedera.hapi.node.base.TransactionID; @@ -38,7 +39,6 @@ import com.hedera.node.app.service.contract.impl.exec.CallOutcome; import com.hedera.node.app.service.contract.impl.exec.ContextTransactionProcessor; import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.failure.AbortException; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; import com.hedera.node.app.service.contract.impl.exec.tracers.EvmActionTracer; import com.hedera.node.app.service.contract.impl.hevm.HederaEvmContext; @@ -61,6 +61,9 @@ @ExtendWith(MockitoExtension.class) class ContextTransactionProcessorTest { private static final Configuration CONFIGURATION = HederaTestConfigBuilder.createConfig(); + private static final Configuration CONFIG_NO_CHARGE_ON_EXCEPTION = HederaTestConfigBuilder.create() + .withValue("contracts.evm.chargeGasOnEvmHandleException", false) + .getOrCreateConfig(); @Mock private HandleContext context; @@ -224,10 +227,11 @@ void stillChargesHapiFeesOnAbort() { .willReturn(HEVM_CREATION); given(processor.processTransaction( HEVM_CREATION, rootProxyWorldUpdater, feesOnlyUpdater, hederaEvmContext, tracer, CONFIGURATION)) - .willThrow(new AbortException(INVALID_CONTRACT_ID, SENDER_ID)); + .willThrow(new HandleException(INVALID_CONTRACT_ID)); subject.call(); + verify(customGasCharging).chargeGasForAbortedTransaction(any(), any(), any(), any()); verify(rootProxyWorldUpdater).commit(); } @@ -255,6 +259,36 @@ void stillChargesHapiFeesOnHevmException() { final var outcome = subject.call(); + verify(customGasCharging).chargeGasForAbortedTransaction(any(), any(), any(), any()); + verify(rootProxyWorldUpdater).commit(); + assertEquals(INVALID_CONTRACT_ID, outcome.status()); + } + + @Test + void doesNotChargeHapiFeesOnHevmExceptionIfSoConfiggured() { + final var contractsConfig = CONFIG_NO_CHARGE_ON_EXCEPTION.getConfigData(ContractsConfig.class); + final var subject = new ContextTransactionProcessor( + null, + context, + contractsConfig, + CONFIG_NO_CHARGE_ON_EXCEPTION, + hederaEvmContext, + null, + tracer, + rootProxyWorldUpdater, + hevmTransactionFactory, + feesOnlyUpdater, + processor, + customGasCharging); + + given(context.body()).willReturn(transactionBody); + given(hevmTransactionFactory.fromHapiTransaction(transactionBody)).willReturn(HEVM_Exception); + given(transactionBody.transactionIDOrThrow()).willReturn(transactionID); + given(transactionID.accountIDOrThrow()).willReturn(SENDER_ID); + + final var outcome = subject.call(); + + verify(customGasCharging, never()).chargeGasForAbortedTransaction(any(), any(), any(), any()); verify(rootProxyWorldUpdater).commit(); assertEquals(INVALID_CONTRACT_ID, outcome.status()); } @@ -285,6 +319,38 @@ void stillChargesHapiFeesOnExceptionThrown() { final var outcome = subject.call(); + verify(customGasCharging).chargeGasForAbortedTransaction(any(), any(), any(), any()); + verify(rootProxyWorldUpdater).commit(); + assertEquals(INVALID_CONTRACT_ID, outcome.status()); + } + + @Test + void doesNotChargeHapiFeesOnExceptionThrownIfSoConfigured() { + final var contractsConfig = CONFIG_NO_CHARGE_ON_EXCEPTION.getConfigData(ContractsConfig.class); + final var subject = new ContextTransactionProcessor( + null, + context, + contractsConfig, + CONFIG_NO_CHARGE_ON_EXCEPTION, + hederaEvmContext, + null, + tracer, + rootProxyWorldUpdater, + hevmTransactionFactory, + feesOnlyUpdater, + processor, + customGasCharging); + + given(context.body()).willReturn(transactionBody); + given(hevmTransactionFactory.fromHapiTransaction(transactionBody)) + .willThrow(new HandleException(INVALID_CONTRACT_ID)); + given(hevmTransactionFactory.fromContractTxException(any(), any())).willReturn(HEVM_Exception); + given(transactionBody.transactionIDOrThrow()).willReturn(transactionID); + given(transactionID.accountIDOrThrow()).willReturn(SENDER_ID); + + final var outcome = subject.call(); + + verify(customGasCharging, never()).chargeGasForAbortedTransaction(any(), any(), any(), any()); verify(rootProxyWorldUpdater).commit(); assertEquals(INVALID_CONTRACT_ID, outcome.status()); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java index 657d8c2e079b..ae7110c37a1a 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java @@ -65,7 +65,6 @@ import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; import com.hedera.node.app.service.contract.impl.exec.FrameRunner; import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.failure.AbortException; import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; import com.hedera.node.app.service.contract.impl.exec.gas.SystemContractGasCalculator; import com.hedera.node.app.service.contract.impl.exec.gas.TinybarValues; @@ -78,6 +77,7 @@ import com.hedera.node.app.service.contract.impl.records.ContractOperationStreamBuilder; import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; import com.hedera.node.app.service.contract.impl.utils.ConversionUtils; +import com.hedera.node.app.spi.workflows.HandleException; import com.hedera.node.app.spi.workflows.ResourceExhaustedException; import com.hedera.pbj.runtime.io.buffer.Bytes; import com.swirlds.config.api.Configuration; @@ -163,7 +163,7 @@ void abortsOnMissingSender() { @Test void lazyCreationAttemptWithNoValueFailsFast() { - givenSenderAccount(); + givenSenderAccountWithNoHederaAccount(); givenRelayerAccount(); given(messageCallProcessor.isImplicitCreationEnabled(config)).willReturn(true); assertAbortsWith(wellKnownRelayedHapiCall(0), INVALID_CONTRACT_ID); @@ -171,7 +171,7 @@ void lazyCreationAttemptWithNoValueFailsFast() { @Test void lazyCreationAttemptWithInvalidAddress() { - givenSenderAccount(); + givenSenderAccountWithNoHederaAccount(); givenRelayerAccount(); final var invalidCreation = new HederaEvmTransaction( SENDER_ID, @@ -363,22 +363,22 @@ void callWhenComputePartiesThrowsException() { final var context = wellKnownContextWith(blocks, tinybarValues, systemContractGasCalculator); given(worldUpdater.getHederaAccount(SENDER_ID)).willReturn(null); - final var abortException = catchThrowableOfType( + final var handleException = catchThrowableOfType( () -> subject.processTransaction( transaction, worldUpdater, () -> feesOnlyUpdater, context, tracer, config), - AbortException.class); - assertThat(abortException.isChargeable()).isFalse(); + HandleException.class); + assertThat(handleException.getStatus()).isEqualTo(INVALID_ACCOUNT_ID); } @Test void requiresEthTxToHaveNonNullRelayer() { - givenSenderAccount(); + givenSenderAccountWithNoHederaAccount(); assertAbortsWith(wellKnownRelayedHapiCall(0), INVALID_ACCOUNT_ID); } @Test void nonLazyCreateCandidateMustHaveReceiver() { - givenSenderAccount(); + givenSenderAccountWithNoHederaAccount(); givenRelayerAccount(); assertAbortsWith(wellKnownRelayedHapiCall(0), INVALID_CONTRACT_ID); } @@ -756,8 +756,12 @@ private void givenFeeOnlyParties() { given(feesOnlyUpdater.getHederaAccount(CALLED_CONTRACT_ID)).willReturn(receiverAccount); } - private void givenSenderAccount() { + private void givenSenderAccountWithNoHederaAccount() { given(worldUpdater.getHederaAccount(SENDER_ID)).willReturn(senderAccount); + } + + private void givenSenderAccount() { + givenSenderAccountWithNoHederaAccount(); given(senderAccount.hederaId()).willReturn(SENDER_ID); }