From d30a22fcd462b11dd98fb6f11cc89d8ae2b96050 Mon Sep 17 00:00:00 2001 From: Lev Povolotsky Date: Tue, 27 Jun 2023 09:52:48 -0400 Subject: [PATCH] Revert "Refactor operations to eliminate duplicate code between EVM versions (#7000)" This reverts commit d75dd6ec5c40590faa37953435510fdea38ebc52. --- build.gradle.kts | 12 +- .../ActiveContractVerificationStrategy.java | 81 ----- .../node/app/spi/meta/bni/Dispatch.java | 28 +- .../spi/meta/bni/VerificationStrategy.java | 8 +- ...ctiveContractVerificationStrategyTest.java | 136 -------- .../app/state/merkle/MerkleHederaState.java | 6 +- .../operations/HederaEvmCreate2Operation.java | 2 +- .../gascalculator/GasCalculatorHederaV18.java | 3 +- .../build.gradle.kts | 4 - .../contract/impl/ContractServiceImpl.java | 44 ++- .../contract/impl/ContractServiceModule.java | 62 ++++ .../contract/impl/ServiceComponent.java | 27 -- .../service/contract/impl/ServiceModule.java | 73 ----- .../impl/annotations/ServicesV030.java | 36 -- .../impl/annotations/ServicesV034.java | 36 -- .../impl/annotations/ServicesV038.java | 36 -- .../impl/annotations/ServicesVersionKey.java | 36 -- .../impl/annotations/TransactionScope.java | 13 +- .../contract/impl/exec/AddressChecks.java | 78 ----- .../contract/impl/exec/FeatureFlags.java | 56 ---- .../ServiceComponent.java} | 8 +- .../impl/exec/TransactionComponent.java | 2 +- .../impl/exec/TransactionProcessor.java | 94 +----- .../failure/CustomExceptionalHaltReason.java | 47 --- .../impl/exec/gas/CustomGasCalculator.java | 33 -- .../impl/exec/gas/CustomGasCharging.java | 57 ---- .../impl/exec/gas/GasChargingResult.java | 24 -- .../AbstractCustomCreateOperation.java | 205 ------------ .../operations/CustomBalanceOperation.java | 59 ---- .../operations/CustomCallCodeOperation.java | 47 --- .../exec/operations/CustomCallOperation.java | 89 ----- .../operations/CustomChainIdOperation.java | 57 ---- .../operations/CustomCreate2Operation.java | 94 ------ .../operations/CustomCreateOperation.java | 55 ---- .../CustomDelegateCallOperation.java | 59 ---- .../CustomExtCodeCopyOperation.java | 73 ----- .../CustomExtCodeHashOperation.java | 70 ---- .../CustomExtCodeSizeOperation.java | 63 ---- .../CustomSelfDestructOperation.java | 116 ------- .../exec/operations/CustomizedOpcodes.java | 42 --- .../CustomContractCreationProcessor.java | 35 -- .../CustomMessageCallProcessor.java | 183 ----------- .../impl/exec/processors/ProcessorModule.java | 45 --- .../contract/impl/exec/utils/FrameUtils.java | 48 --- .../contract/impl/exec/v030/V030Module.java | 170 ---------- .../exec/v030/Version030AddressChecks.java | 75 ----- .../exec/v030/Version030FeatureFlags.java | 49 --- .../contract/impl/exec/v034/V034Module.java | 171 ---------- .../exec/v034/Version034FeatureFlags.java | 43 --- .../contract/impl/exec/v038/V038Module.java | 172 ---------- .../exec/v038/Version038AddressChecks.java | 52 --- .../contract/impl/hevm/HederaEvmBlocks.java | 57 ---- .../contract/impl/hevm/HederaEvmContext.java | 19 -- .../impl/hevm/HederaEvmTransaction.java | 56 ---- .../hevm/HederaEvmTransactionProcessor.java | 54 --- .../impl/hevm/HederaEvmTransactionResult.java | 52 --- .../impl/hevm/HederaWorldUpdater.java | 158 --------- .../impl/state/AbstractMutableEvmAccount.java | 4 +- .../impl/state/BaseProxyWorldUpdater.java | 2 +- .../contract/impl/state/ContractSchema.java | 58 ---- .../impl/state/DispatchingEvmFrameState.java | 189 +---------- .../contract/impl/state/EvmFrameState.java | 114 +------ .../contract/impl/state/HederaEvmAccount.java | 28 -- .../contract/impl/state/ProxyEvmAccount.java | 36 -- .../impl/state/ProxyWorldUpdater.java | 154 +++------ .../contract/impl/state/TokenEvmAccount.java | 8 - .../src/main/java/module-info.java | 26 +- .../impl/test/ContractServiceImplTest.java | 28 +- .../impl/test/ServiceComponentTest.java | 32 -- .../contract/impl/test/TestHelpers.java | 124 ------- .../test/exec/TransactionProcessorTest.java | 118 ------- .../test/exec/gas/CustomGasChargingTest.java | 60 ---- .../operations/CreateOperationTestBase.java | 102 ------ .../CustomBalanceOperationTest.java | 108 ------ .../operations/CustomCallOperationTest.java | 167 ---------- .../CustomChainIdOperationTest.java | 77 ----- .../CustomCreate2OperationTest.java | 104 ------ .../operations/CustomCreateOperationTest.java | 146 --------- .../CustomDelegateCallOperationTest.java | 107 ------ .../CustomExtCodeCopyOperationTest.java | 108 ------ .../CustomExtCodeHashOperationTest.java | 103 ------ .../CustomExtCodeSizeOperationTest.java | 95 ------ .../CustomSelfDestructOperationTest.java | 165 ---------- .../CustomMessageCallProcessorTest.java | 272 --------------- .../v030/Version030AddressChecksTest.java | 98 ------ .../exec/v030/Version030FeatureFlagsTest.java | 53 --- .../exec/v034/Version034FeatureFlagsTest.java | 63 ---- .../v038/Version038AddressChecksTest.java | 45 --- .../HederaEvmTransactionProcessorTest.java | 99 ------ .../hevm/HederaEvmTransactionResultTest.java | 35 -- .../test/hevm/HederaEvmTransactionTest.java | 38 --- .../test/state/BaseProxyWorldUpdaterTest.java | 4 +- .../state/DispatchingEvmFrameStateTest.java | 309 +----------------- .../impl/test/state/EvmFrameStateTest.java | 6 +- .../impl/test/state/ProxyEvmAccountTest.java | 11 - .../test/state/ProxyWorldUpdaterTest.java | 89 +---- .../impl/test/state/TokenEvmAccountTest.java | 10 +- .../src/test/java/module-info.java | 26 +- 98 files changed, 197 insertions(+), 6734 deletions(-) delete mode 100644 hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategy.java delete mode 100644 hedera-node/hedera-app-spi/src/test/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategyTest.java create mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceModule.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceComponent.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceModule.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV030.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV034.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV038.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesVersionKey.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/AddressChecks.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/FeatureFlags.java rename hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/{hevm/HederaEvmVersion.java => exec/ServiceComponent.java} (81%) delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/CustomExceptionalHaltReason.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCalculator.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCharging.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/GasChargingResult.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/AbstractCustomCreateOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomBalanceOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallCodeOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomChainIdOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreate2Operation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreateOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomDelegateCallOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeCopyOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeHashOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeSizeOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomSelfDestructOperation.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomizedOpcodes.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomContractCreationProcessor.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/ProcessorModule.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/FrameUtils.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/V030Module.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030AddressChecks.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030FeatureFlags.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/V034Module.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/Version034FeatureFlags.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/V038Module.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/Version038AddressChecks.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmBlocks.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmContext.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionProcessor.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionResult.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaWorldUpdater.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ContractSchema.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/HederaEvmAccount.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ServiceComponentTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/TestHelpers.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/gas/CustomGasChargingTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CreateOperationTestBase.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomBalanceOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCallOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomChainIdOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreate2OperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreateOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomDelegateCallOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeCopyOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeHashOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeSizeOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomSelfDestructOperationTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/processors/CustomMessageCallProcessorTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030AddressChecksTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030FeatureFlagsTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v034/Version034FeatureFlagsTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v038/Version038AddressChecksTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionProcessorTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionResultTest.java delete mode 100644 hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionTest.java diff --git a/build.gradle.kts b/build.gradle.kts index cf9586cf4d4e..2e46d088ad59 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,13 +15,13 @@ */ plugins { - id("com.hedera.hashgraph.aggregate-reports") - id("com.hedera.hashgraph.spotless-conventions") - id("com.hedera.hashgraph.spotless-kotlin-conventions") - id("com.hedera.hashgraph.dependency-analysis") + id("com.hedera.hashgraph.aggregate-reports") + id("com.hedera.hashgraph.spotless-conventions") + id("com.hedera.hashgraph.spotless-kotlin-conventions") + id("com.hedera.hashgraph.dependency-analysis") } repositories { - mavenCentral() - maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } + mavenCentral() + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") } } diff --git a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategy.java b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategy.java deleted file mode 100644 index 63821d6a5574..000000000000 --- a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategy.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.spi.meta.bni; - -import com.hedera.hapi.node.base.ContractID; -import com.hedera.hapi.node.base.Key; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; - -/** - * A {@link VerificationStrategy} that verifies signatures from a single active contract. This is the - * verification strategy used within the EVM to check receiver signature requirements. - */ -public class ActiveContractVerificationStrategy implements VerificationStrategy { - private final long activeNumber; - private final Bytes activeAddress; - private final boolean requiresDelegatePermission; - - public ActiveContractVerificationStrategy( - final long activeNumber, @NonNull final Bytes activeAddress, final boolean requiresDelegatePermission) { - this.activeNumber = activeNumber; - this.activeAddress = Objects.requireNonNull(activeAddress); - this.requiresDelegatePermission = requiresDelegatePermission; - } - - /** - * {@inheritDoc} - */ - @Override - public Decision maybeVerifySignature(@NonNull final Key key, @NonNull final KeyRole keyRole) { - final var keyKind = key.key().kind(); - if (keyKind == Key.KeyOneOfType.CONTRACT_ID) { - if (requiresDelegatePermission) { - return Decision.INVALID; - } else { - return decisionFor(key.contractIDOrThrow()); - } - } else if (keyKind == Key.KeyOneOfType.DELEGATABLE_CONTRACT_ID) { - return decisionFor(key.delegatableContractIdOrThrow()); - } else { - return Decision.DELEGATE_TO_CRYPTOGRAPHIC_VERIFICATION; - } - } - - public long getActiveNumber() { - return activeNumber; - } - - public Bytes getActiveAddress() { - return activeAddress; - } - - public boolean requiresDelegatePermission() { - return requiresDelegatePermission; - } - - private Decision decisionFor(@NonNull final ContractID authorizedId) { - if (authorizedId.hasContractNum() && authorizedId.contractNumOrThrow() == activeNumber) { - return Decision.VALID; - } else if (authorizedId.hasEvmAddress() && activeAddress.equals(authorizedId.evmAddress())) { - return Decision.VALID; - } else { - return Decision.INVALID; - } - } -} diff --git a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/Dispatch.java b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/Dispatch.java index fd5f4575ed6e..540da7f3c89a 100644 --- a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/Dispatch.java +++ b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/Dispatch.java @@ -141,25 +141,9 @@ TokenRelationship getRelationshipAndExternalizeResult( * @param strategy the {@link VerificationStrategy} to use * @return the result of the transfer attempt */ - ResponseCodeEnum transferWithReceiverSigCheck( + ResponseCodeEnum transferValue( long amount, long fromEntityNumber, long toEntityNumber, @NonNull VerificationStrategy strategy); - /** - * Collects the given {@code amount} of fees from the given {@code fromEntityNumber}. - * - * @param fromEntityNumber the number of the entity to collect fees from - * @param amount the amount of fees to collect - */ - void collectFee(long fromEntityNumber, long amount); - - /** - * Refunds the given {@code amount} of fees from the given {@code fromEntityNumber}. - * - * @param fromEntityNumber the number of the entity to refund fees to - * @param amount the amount of fees to collect - */ - void refundFee(long fromEntityNumber, long amount); - /** * Links the given {@code evmAddress} to the given {@code entityNumber} as an alias. * @@ -312,14 +296,4 @@ ResponseCodeEnum transferWithReceiverSigCheck( */ @Nullable Nft getNft(@NonNull UniqueTokenId id); - - // --- (SECTION V) Miscellaneous methods - /** - * Tracks the deletion of a contract and the beneficiary that should receive any staking awards otherwise - * earned by the deleted contract. - * - * @param deletedNumber the number of the deleted contract - * @param beneficiaryNumber the number of the beneficiary - */ - void trackDeletion(long deletedNumber, long beneficiaryNumber); } diff --git a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/VerificationStrategy.java b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/VerificationStrategy.java index b65e06054017..dfd9b5d543ea 100644 --- a/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/VerificationStrategy.java +++ b/hedera-node/hedera-app-spi/src/main/java/com/hedera/node/app/spi/meta/bni/VerificationStrategy.java @@ -34,7 +34,7 @@ * *

Because it possible for the {@code tokenTransfer()} system contract to need to amend * its dispatched transaction based on the results of signature verifications, the strategy - * also has the option to return an amended transaction body when this occurs. + * also has the option to return an amended transaction body when an . */ public interface VerificationStrategy { enum Decision { @@ -74,8 +74,6 @@ enum KeyRole { * @return an amended CryptoTransfer, or null if no amendment is necessary */ @Nullable - default CryptoTransferTransactionBody maybeAmendTransfer( - @NonNull CryptoTransferTransactionBody transfer, List invalidSignerNumbers) { - throw new UnsupportedOperationException("Default verification strategy does not amend transfers"); - } + CryptoTransferTransactionBody maybeAmendTransfer( + @NonNull CryptoTransferTransactionBody transfer, List invalidSignerNumbers); } diff --git a/hedera-node/hedera-app-spi/src/test/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategyTest.java b/hedera-node/hedera-app-spi/src/test/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategyTest.java deleted file mode 100644 index 9729a448333f..000000000000 --- a/hedera-node/hedera-app-spi/src/test/java/com/hedera/node/app/spi/meta/bni/ActiveContractVerificationStrategyTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.spi.meta.bni; - -import static org.junit.jupiter.api.Assertions.*; - -import com.hedera.hapi.node.base.ContractID; -import com.hedera.hapi.node.base.Key; -import com.hedera.hapi.node.token.CryptoTransferTransactionBody; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import java.util.List; -import org.junit.jupiter.api.Test; - -class ActiveContractVerificationStrategyTest { - private static final long ACTIVE_NUMBER = 1234L; - private static final long SOME_OTHER_NUMBER = 2345L; - private static final Bytes ACTIVE_ADDRESS = Bytes.fromHex("1234"); - private static final Bytes OTHER_ADDRESS = Bytes.fromHex("abcd"); - - private static final Key ACTIVE_ID_KEY = Key.newBuilder() - .contractID(ContractID.newBuilder().contractNum(ACTIVE_NUMBER)) - .build(); - private static final Key DELEGATABLE_ACTIVE_ID_KEY = Key.newBuilder() - .delegatableContractId(ContractID.newBuilder().contractNum(ACTIVE_NUMBER)) - .build(); - private static final Key INACTIVE_ID_KEY = Key.newBuilder() - .contractID(ContractID.newBuilder().contractNum(SOME_OTHER_NUMBER)) - .build(); - private static final Key DELEGATABLE_INACTIVE_ID_KEY = Key.newBuilder() - .delegatableContractId(ContractID.newBuilder().contractNum(SOME_OTHER_NUMBER)) - .build(); - private static final Key ACTIVE_ADDRESS_KEY = Key.newBuilder() - .contractID(ContractID.newBuilder().evmAddress(ACTIVE_ADDRESS)) - .build(); - private static final Key DELEGATABLE_ACTIVE_ADDRESS_KEY = Key.newBuilder() - .delegatableContractId(ContractID.newBuilder().evmAddress(ACTIVE_ADDRESS)) - .build(); - private static final Key INACTIVE_ADDRESS_KEY = Key.newBuilder() - .contractID(ContractID.newBuilder().evmAddress(OTHER_ADDRESS)) - .build(); - private static final Key DELEGATABLE_INACTIVE_ADDRESS_KEY = Key.newBuilder() - .delegatableContractId(ContractID.newBuilder().evmAddress(OTHER_ADDRESS)) - .build(); - private static final Key CRYPTO_KEY = Key.newBuilder() - .ed25519(Bytes.fromHex("1234567812345678123456781234567812345678123456781234567812345678")) - .build(); - - @Test - void validatesKeysAsExpectedWhenDelegatePermissionNotRequired() { - final var subject = new ActiveContractVerificationStrategy(ACTIVE_NUMBER, ACTIVE_ADDRESS, false); - - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(ACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(ACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(INACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(INACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(DELEGATABLE_ACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(DELEGATABLE_ACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(DELEGATABLE_INACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(DELEGATABLE_INACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.DELEGATE_TO_CRYPTOGRAPHIC_VERIFICATION, - subject.maybeVerifySignature(CRYPTO_KEY, VerificationStrategy.KeyRole.OTHER)); - } - - @Test - void validatesKeysAsExpectedWhenDelegatePermissionRequired() { - final var subject = new ActiveContractVerificationStrategy(ACTIVE_NUMBER, ACTIVE_ADDRESS, true); - - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(ACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(ACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(INACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(INACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(DELEGATABLE_ACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.VALID, - subject.maybeVerifySignature(DELEGATABLE_ACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(DELEGATABLE_INACTIVE_ID_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.INVALID, - subject.maybeVerifySignature(DELEGATABLE_INACTIVE_ADDRESS_KEY, VerificationStrategy.KeyRole.OTHER)); - assertEquals( - VerificationStrategy.Decision.DELEGATE_TO_CRYPTOGRAPHIC_VERIFICATION, - subject.maybeVerifySignature(CRYPTO_KEY, VerificationStrategy.KeyRole.OTHER)); - } - - @Test - void doesNotSupportAmendingTransfer() { - final var subject = new ActiveContractVerificationStrategy(ACTIVE_NUMBER, ACTIVE_ADDRESS, true); - - assertThrows( - UnsupportedOperationException.class, - () -> subject.maybeAmendTransfer(CryptoTransferTransactionBody.DEFAULT, List.of())); - } -} diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/merkle/MerkleHederaState.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/merkle/MerkleHederaState.java index 7fb10b4198fa..06a07a22be7d 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/merkle/MerkleHederaState.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/merkle/MerkleHederaState.java @@ -20,7 +20,7 @@ import com.hedera.node.app.service.consensus.ConsensusService; import com.hedera.node.app.service.consensus.impl.ConsensusServiceImpl; import com.hedera.node.app.service.contract.ContractService; -import com.hedera.node.app.service.contract.impl.state.ContractSchema; +import com.hedera.node.app.service.contract.impl.ContractServiceImpl; import com.hedera.node.app.service.file.FileService; import com.hedera.node.app.service.file.impl.FileServiceImpl; import com.hedera.node.app.service.mono.context.StateChildrenProvider; @@ -762,8 +762,8 @@ public VirtualMapLike storage() { public VirtualMapLike contractStorage() { return VirtualMapLikeAdapter.unwrapping( (StateMetadata) - services.get(ContractService.NAME).get(ContractSchema.STORAGE_KEY), - getChild(findNodeIndex(ContractService.NAME, ContractSchema.STORAGE_KEY))); + services.get(ContractService.NAME).get(ContractServiceImpl.STORAGE_KEY), + getChild(findNodeIndex(ContractService.NAME, ContractServiceImpl.STORAGE_KEY))); } @Override diff --git a/hedera-node/hedera-evm/src/main/java/com/hedera/node/app/service/evm/contracts/operations/HederaEvmCreate2Operation.java b/hedera-node/hedera-evm/src/main/java/com/hedera/node/app/service/evm/contracts/operations/HederaEvmCreate2Operation.java index eb209f71c85a..4f0363990392 100644 --- a/hedera-node/hedera-evm/src/main/java/com/hedera/node/app/service/evm/contracts/operations/HederaEvmCreate2Operation.java +++ b/hedera-node/hedera-evm/src/main/java/com/hedera/node/app/service/evm/contracts/operations/HederaEvmCreate2Operation.java @@ -78,7 +78,7 @@ public Address targetContractAddress(final MessageFrame frame) { return alias; } - public static Bytes32 keccak256(final Bytes input) { + private static Bytes32 keccak256(final Bytes input) { return Bytes32.wrap(keccak256DigestOf(input.toArrayUnsafe())); } diff --git a/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/gascalculator/GasCalculatorHederaV18.java b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/gascalculator/GasCalculatorHederaV18.java index 34a10a6dfa66..e328c834d908 100644 --- a/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/gascalculator/GasCalculatorHederaV18.java +++ b/hedera-node/hedera-mono-service/src/main/java/com/hedera/node/app/service/mono/contracts/gascalculator/GasCalculatorHederaV18.java @@ -41,7 +41,6 @@ import com.hedera.node.app.service.mono.context.properties.GlobalDynamicProperties; import com.hedera.node.app.service.mono.fees.HbarCentExchange; import com.hedera.node.app.service.mono.fees.calculation.UsagePricesProvider; -import edu.umd.cs.findbugs.annotations.Nullable; import javax.inject.Inject; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Wei; @@ -128,7 +127,7 @@ public long extCodeHashOperationGasCost() { } @Override - public long selfDestructOperationGasCost(@Nullable final Account recipient, final Wei inheritance) { + public long selfDestructOperationGasCost(final Account recipient, final Wei inheritance) { // Frontier gas cost return 0; } diff --git a/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts b/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts index 93bfb1d450b0..6752628d3522 100644 --- a/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts +++ b/hedera-node/hedera-smart-contract-service-impl/build.gradle.kts @@ -28,10 +28,6 @@ dependencies { } } -val generatedSources = file("build/generated/sources/annotationProcessor/java/main") - -java.sourceSets["main"].java.srcDir(generatedSources) - // TODO module-info.java in 'test' // https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin/issues/900 dependencyAnalysis.issues { 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 2d75b66bdd1e..e395c8839cc3 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 @@ -16,28 +16,50 @@ package com.hedera.node.app.service.contract.impl; +import com.hedera.hapi.node.base.SemanticVersion; import com.hedera.node.app.service.contract.ContractService; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionProcessor; -import com.hedera.node.app.service.contract.impl.state.ContractSchema; +import com.hedera.node.app.service.mono.state.codec.MonoMapCodecAdapter; +import com.hedera.node.app.service.mono.state.virtual.ContractKey; +import com.hedera.node.app.service.mono.state.virtual.ContractKeySerializer; +import com.hedera.node.app.service.mono.state.virtual.IterableContractValue; +import com.hedera.node.app.spi.state.Schema; import com.hedera.node.app.spi.state.SchemaRegistry; +import com.hedera.node.app.spi.state.StateDefinition; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.Set; /** - * Standard implementation of the {@link ContractService}. + * Standard implementation of the {@link ContractService} {@link com.hedera.node.app.spi.Service}. */ public final class ContractServiceImpl implements ContractService { - private final HederaEvmTransactionProcessor transactionProcessor; + private static final int MAX_STORAGE_ENTRIES = 4096; + private static final SemanticVersion CURRENT_VERSION = + SemanticVersion.newBuilder().minor(34).build(); + public static final String STORAGE_KEY = "STORAGE"; + public static final String BYTECODE_KEY = "BYTECODE"; - public ContractServiceImpl() { - transactionProcessor = DaggerServiceComponent.create().transactionProcessor(); + @Override + public void registerSchemas(@NonNull SchemaRegistry registry) { + registry.register(contractSchema()); } - @Override - public void registerSchemas(@NonNull final SchemaRegistry registry) { - registry.register(new ContractSchema()); + private Schema contractSchema() { + return new Schema(CURRENT_VERSION) { + @NonNull + @Override + @SuppressWarnings("rawtypes") + public Set statesToCreate() { + return Set.of(storageDef()); + } + }; } - public HederaEvmTransactionProcessor transactionProcessor() { - return transactionProcessor; + private static StateDefinition storageDef() { + final var keySerdes = MonoMapCodecAdapter.codecForVirtualKey( + ContractKey.MERKLE_VERSION, ContractKey::new, new ContractKeySerializer()); + final var valueSerdes = MonoMapCodecAdapter.codecForVirtualValue( + IterableContractValue.ITERABLE_VERSION, IterableContractValue::new); + + return StateDefinition.onDisk(STORAGE_KEY, keySerdes, valueSerdes, MAX_STORAGE_ENTRIES); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceModule.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceModule.java new file mode 100644 index 000000000000..f04762975cf4 --- /dev/null +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ContractServiceModule.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.node.app.service.contract.impl; + +import com.hedera.node.app.service.contract.impl.handlers.ContractCallHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractCallLocalHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractCreateHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractDeleteHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractGetBySolidityIDHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractGetBytecodeHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractGetInfoHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractGetRecordsHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractHandlers; +import com.hedera.node.app.service.contract.impl.handlers.ContractSystemDeleteHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractSystemUndeleteHandler; +import com.hedera.node.app.service.contract.impl.handlers.ContractUpdateHandler; +import com.hedera.node.app.service.contract.impl.handlers.EtherumTransactionHandler; +import dagger.Module; + +@Module +public interface ContractServiceModule { + + ContractCallHandler contractCallHandler(); + + ContractCallLocalHandler contractCallLocalHandler(); + + ContractCreateHandler contractCreateHandler(); + + ContractDeleteHandler contractDeleteHandler(); + + ContractGetBySolidityIDHandler contractGetBySolidityIDHandler(); + + ContractGetBytecodeHandler contractGetBytecodeHandler(); + + ContractGetInfoHandler contractGetInfoHandler(); + + ContractGetRecordsHandler contractGetRecordsHandler(); + + ContractSystemDeleteHandler contractSystemDeleteHandler(); + + ContractSystemUndeleteHandler contractSystemUndeleteHandler(); + + ContractUpdateHandler contractUpdateHandler(); + + EtherumTransactionHandler etherumTransactionHandler(); + + ContractHandlers contractHandlers(); +} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceComponent.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceComponent.java deleted file mode 100644 index f6ef51b01768..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceComponent.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl; - -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionProcessor; -import dagger.Component; -import javax.inject.Singleton; - -@Singleton -@Component(modules = {ServiceModule.class}) -public interface ServiceComponent { - HederaEvmTransactionProcessor transactionProcessor(); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceModule.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceModule.java deleted file mode 100644 index 6c58b8e7892a..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/ServiceModule.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl; - -import static com.hedera.node.app.service.contract.impl.hevm.HederaEvmVersion.VERSION_030; -import static com.hedera.node.app.service.contract.impl.hevm.HederaEvmVersion.VERSION_034; -import static com.hedera.node.app.service.contract.impl.hevm.HederaEvmVersion.VERSION_038; - -import com.hedera.node.app.service.contract.impl.annotations.ServicesV030; -import com.hedera.node.app.service.contract.impl.annotations.ServicesV034; -import com.hedera.node.app.service.contract.impl.annotations.ServicesV038; -import com.hedera.node.app.service.contract.impl.annotations.ServicesVersionKey; -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCalculator; -import com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule; -import com.hedera.node.app.service.contract.impl.exec.v030.V030Module; -import com.hedera.node.app.service.contract.impl.exec.v034.V034Module; -import com.hedera.node.app.service.contract.impl.exec.v038.V038Module; -import dagger.Binds; -import dagger.Module; -import dagger.multibindings.IntoMap; -import dagger.multibindings.Multibinds; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; - -/** - * Provides bindings for the {@link TransactionProcessor} implementations used by each - * version of the Hedera EVM, along with infrastructure like the {@link GasCalculator} - * and Hedera {@link PrecompiledContract} instances that have not changed since the - * first EVM version we explicitly support (which is {@code v0.30}). - */ -@Module(includes = {V030Module.class, V034Module.class, V038Module.class, ProcessorModule.class}) -public interface ServiceModule { - @Binds - @Singleton - GasCalculator bindGasCalculator(@NonNull final CustomGasCalculator gasCalculator); - - @Multibinds - Map bindHederaPrecompiles(); - - @Binds - @IntoMap - @ServicesVersionKey(VERSION_030) - TransactionProcessor bindV030Processor(@ServicesV030 @NonNull final TransactionProcessor processor); - - @Binds - @IntoMap - @ServicesVersionKey(VERSION_034) - TransactionProcessor bindV034Processor(@ServicesV034 @NonNull final TransactionProcessor processor); - - @Binds - @IntoMap - @ServicesVersionKey(VERSION_038) - TransactionProcessor bindV038Processor(@ServicesV038 @NonNull final TransactionProcessor processor); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV030.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV030.java deleted file mode 100644 index ba17321be3e8..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV030.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.annotations; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; -import javax.inject.Qualifier; - -/** - * Qualifies a binding for use with the {@code v0.30} Services EVM. - */ -@Target({METHOD, PARAMETER, TYPE}) -@Retention(RUNTIME) -@Documented -@Qualifier -public @interface ServicesV030 {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV034.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV034.java deleted file mode 100644 index 65b8a644cb8d..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV034.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.annotations; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; -import javax.inject.Qualifier; - -/** - * Qualifies a binding for use with the {@code v0.34} Services EVM. - */ -@Target({METHOD, PARAMETER, TYPE}) -@Retention(RUNTIME) -@Documented -@Qualifier -public @interface ServicesV034 {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV038.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV038.java deleted file mode 100644 index 9073d150ac10..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesV038.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.annotations; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; -import javax.inject.Qualifier; - -/** - * Qualifies a binding for use with the {@code v0.38} Services EVM. - */ -@Target({METHOD, PARAMETER, TYPE}) -@Retention(RUNTIME) -@Documented -@Qualifier -public @interface ServicesV038 {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesVersionKey.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesVersionKey.java deleted file mode 100644 index 5b5e5982049c..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/ServicesVersionKey.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.annotations; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmVersion; -import dagger.MapKey; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Target({METHOD, PARAMETER, TYPE}) -@Retention(RUNTIME) -@Documented -@MapKey -public @interface ServicesVersionKey { - HederaEvmVersion value(); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/TransactionScope.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/TransactionScope.java index 6219e5db54fe..aa00eaaf4609 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/TransactionScope.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/annotations/TransactionScope.java @@ -16,22 +16,11 @@ package com.hedera.node.app.service.contract.impl.annotations; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.annotation.Documented; import java.lang.annotation.Retention; -import java.lang.annotation.Target; import javax.inject.Scope; -/** - * Scope for bindings whose lifetime consists of a single transaction. (There are just enough of these that - * it is helpful to have some DI support.) - */ -@Target({METHOD, PARAMETER, TYPE}) -@Retention(RUNTIME) -@Documented @Scope +@Retention(RUNTIME) public @interface TransactionScope {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/AddressChecks.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/AddressChecks.java deleted file mode 100644 index 9517ed88bd73..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/AddressChecks.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec; - -import edu.umd.cs.findbugs.annotations.NonNull; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; - -/** - * Provides address checks used to customize behavior of Hedera {@link org.hyperledger.besu.evm.operation.Operation} - * or {@link AbstractMessageProcessor} overrides. (The main way the Hedera EVM customizes Besu is by giving special - * treatment to missing and/or system addresses.) - */ -public interface AddressChecks { - /** - * Returns {@code true} if the given address is present in the given frame. This could mean the address is - * a precompile; or a user-space account whose priority address is the given address; or a token "address" - * whose code will redirect ERC-20/ERC-721 token operations to the {@code 0x167} system contract. - * - * @param address the address to check - * @param frame the frame to check - * @return whether the address is present in the frame - */ - boolean isPresent(@NonNull Address address, @NonNull MessageFrame frame); - - /** - * Returns {@code true} if the given address is a system address (i.e. a long-zero address for an entity - * id up to {@code 0.0.750}). - * - * @param address the address to check - * @return whether the address is a system address - */ - boolean isSystemAccount(@NonNull Address address); - - /** - * Returns {@code true} if the given address is a non-user account (i.e. a long-zero address for an entity - * id up to {@code 0.0.1000}). - * - * @param address the address to check - * @return whether the address is a non-user account - */ - boolean isNonUserAccount(@NonNull Address address); - - /** - * A convenience method to check if the given address is completely missing from the given frame. (I.e., - * neither a system account nor present in the sense of {@link AddressChecks#isPresent(Address, MessageFrame)}.) - * - * @param address the address to check - * @param frame the frame to check - * @return whether the address is missing from the frame - */ - default boolean isNeitherSystemNorPresent(@NonNull Address address, @NonNull MessageFrame frame) { - return !isSystemAccount(address) && !isPresent(address, frame); - } - - /** - * Returns {@code true} if the given address is a Hedera precompile. - * - * @param address the address to check - * @return whether the address is a Hedera precompile - */ - boolean isHederaPrecompile(@NonNull Address address); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/FeatureFlags.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/FeatureFlags.java deleted file mode 100644 index ba170ca3acc5..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/FeatureFlags.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec; - -import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.configOf; - -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.hyperledger.besu.evm.frame.MessageFrame; - -/** - * Provides feature flags used to customize behavior of Hedera {@link org.hyperledger.besu.evm.operation.Operation} overrides. - */ -public interface FeatureFlags { - /** - * Whether the {@code CREATE2} operation should be enabled for the given {@code frame}. - * - * @param frame the {@link MessageFrame} to check - * @return whether {@code CREATE2} should be enabled - */ - boolean isCreate2Enabled(@NonNull MessageFrame frame); - - /** - * Whether "implicit creation" of accounts via sending value or targeting a {@code CREATE2} to an EIP-1014 address - * should be enabled for the given {@code frame}. - * - * @param frame the {@link MessageFrame} to check - * @return whether implicit creation should be enabled - */ - default boolean isImplicitCreationEnabled(@NonNull MessageFrame frame) { - return isImplicitCreationEnabled(configOf(frame)); - } - - /** - * Whether "implicit creation" of accounts via sending value or targeting a {@code CREATE2} to an EIP-1014 address - * should be enabled for the given {@code frame}. - * - * @param config the {@link Configuration} to check - * @return whether implicit creation should be enabled - */ - boolean isImplicitCreationEnabled(@NonNull Configuration config); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmVersion.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ServiceComponent.java similarity index 81% rename from hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmVersion.java rename to hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ServiceComponent.java index 48ef181a7c47..c90f667d6341 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmVersion.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/ServiceComponent.java @@ -14,10 +14,6 @@ * limitations under the License. */ -package com.hedera.node.app.service.contract.impl.hevm; +package com.hedera.node.app.service.contract.impl.exec; -public enum HederaEvmVersion { - VERSION_030, - VERSION_034, - VERSION_038 -} +public interface ServiceComponent {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionComponent.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionComponent.java index e7274ebf923c..ea50635105c6 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionComponent.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/TransactionComponent.java @@ -25,8 +25,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; import java.time.Instant; -@Subcomponent @TransactionScope +@Subcomponent public interface TransactionComponent { @Subcomponent.Factory interface Factory { 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 a27a9b11301b..fd39e9235c9f 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 @@ -16,95 +16,7 @@ package com.hedera.node.app.service.contract.impl.exec; -import static com.hedera.hapi.node.base.ResponseCodeEnum.*; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToBesuAddress; -import static com.hedera.node.app.spi.workflows.HandleException.validateTrue; +import javax.inject.Singleton; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import com.hedera.node.app.service.contract.impl.hevm.*; -import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import com.hedera.node.app.spi.workflows.HandleException; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Objects; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; -import org.hyperledger.besu.evm.tracing.OperationTracer; - -/** - * Modeled after the Besu {@code MainnetTransactionProcessor}, so that all four HAPI - * contract operations ({@code ContractCall}, {@code ContractCreate}, {@code EthereumTransaction}, - * {@code ContractCallLocal}) can reduce to a single code path. - */ -public class TransactionProcessor { - public static final String CONFIG_CONTEXT_VARIABLE = "contractsConfig"; - - private final GasCalculator gasCalculator; - private final CustomMessageCallProcessor messageCallProcessor; - private final ContractCreationProcessor contractCreationProcessor; - - public TransactionProcessor( - @NonNull final GasCalculator gasCalculator, - @NonNull final CustomMessageCallProcessor messageCallProcessor, - @NonNull final ContractCreationProcessor contractCreationProcessor) { - this.gasCalculator = Objects.requireNonNull(gasCalculator); - this.messageCallProcessor = Objects.requireNonNull(messageCallProcessor); - this.contractCreationProcessor = Objects.requireNonNull(contractCreationProcessor); - } - - public HederaEvmTransactionResult processTransaction( - @NonNull final HederaEvmTransaction transaction, - @NonNull final HederaWorldUpdater worldUpdater, - @NonNull final HederaEvmContext context, - @NonNull final OperationTracer tracer, - @NonNull final Configuration config) { - try { - final var initialCall = computeInitialCall(transaction, worldUpdater, context, config); - // TODO - use CustomGasCharging when finished - } catch (final HandleException failure) { - return HederaEvmTransactionResult.abortFor(failure.getStatus()); - } - throw new AssertionError("Not implemented"); - } - - private record InitialCall(@NonNull HederaEvmAccount fromAccount, @NonNull Address toAddress) {} - - private InitialCall computeInitialCall( - @NonNull final HederaEvmTransaction transaction, - @NonNull final HederaWorldUpdater worldUpdater, - @NonNull final HederaEvmContext context, - @NonNull final Configuration config) { - - final var from = worldUpdater.getHederaAccount(transaction.senderId()); - validateTrue(from != null, INVALID_ACCOUNT_ID); - if (transaction.isCreate()) { - throw new AssertionError("Not implemented"); - } else { - final var to = worldUpdater.getHederaAccount(transaction.contractIdOrThrow()); - if (maybeLazyCreate(transaction, to, config)) { - validateTrue(transaction.hasValue(), INVALID_CONTRACT_ID); - final var evmAddress = transaction.contractIdOrThrow().evmAddressOrThrow(); - return new InitialCall(from, pbjToBesuAddress(evmAddress)); - } - } - throw new AssertionError("Not implemented"); - } - - private void chargeGasFor( - @NonNull final InitialCall initialCall, - @NonNull final HederaEvmContext context, - @NonNull final HederaEvmTransaction transaction) { - final var upfrontCost = transaction.upfrontCostGiven(context.gasPrice()); - final var payerBalance = initialCall.fromAccount.getBalance().toLong(); - validateTrue(payerBalance >= upfrontCost, INSUFFICIENT_PAYER_BALANCE); - } - - private boolean maybeLazyCreate( - @NonNull final HederaEvmTransaction transaction, - @Nullable final HederaEvmAccount to, - @NonNull final Configuration config) { - return to == null && transaction.relayerId() != null && messageCallProcessor.isImplicitCreationEnabled(config); - } -} +@Singleton +public class TransactionProcessor {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/CustomExceptionalHaltReason.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/CustomExceptionalHaltReason.java deleted file mode 100644 index 8d61da4877b2..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/failure/CustomExceptionalHaltReason.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.failure; - -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; - -/** - * Some {@link ExceptionalHaltReason}s that are not part of the Besu core. - */ -public enum CustomExceptionalHaltReason implements ExceptionalHaltReason { - /** - * An EVM operation referenced an account that does not exist. - */ - MISSING_ADDRESS("Invalid account reference"), - TOKEN_TREASURY_SELFDESTRUCT("Token treasury cannot be deleted"), - TOKEN_HOLDER_SELFDESTRUCT("Accounts still holding tokens cannot be deleted"), - SELFDESTRUCT_TO_SELF("Selfdestruct must give a different beneficiary"), - INVALID_RECEIVER_SIGNATURE("Receiver signature required but not provided"), - TOO_MANY_CHILD_RECORDS("Too many child records for available slots"), - ACCOUNTS_LIMIT_REACHED("Accounts limit reached"), - INVALID_VALUE_TRANSFER("Value transfer not allowed to system or expired accounts"); - - private final String description; - - CustomExceptionalHaltReason(final String description) { - this.description = description; - } - - @Override - public String getDescription() { - return description; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCalculator.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCalculator.java deleted file mode 100644 index ad7c6869aff7..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCalculator.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.gas; - -import javax.inject.Inject; -import javax.inject.Singleton; -import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; - -/** - * Need to clean up and refactor {@link com.hedera.node.app.service.mono.contracts.gascalculator.GasCalculatorHederaV22} - * to get its price and exchange rate from the transaction's {@link com.hedera.node.app.spi.meta.bni.Scope}. - */ -@Singleton -public class CustomGasCalculator extends LondonGasCalculator { - @Inject - public CustomGasCalculator() { - // Dagger2 - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCharging.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCharging.java deleted file mode 100644 index 178655d29742..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/CustomGasCharging.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.gas; - -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmContext; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransaction; -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 edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import javax.inject.Singleton; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; - -@Singleton -public class CustomGasCharging { - private final GasCalculator gasCalculator; - - public CustomGasCharging(@NonNull final GasCalculator gasCalculator) { - this.gasCalculator = gasCalculator; - } - - /** - * Tries to charge gas for the given transaction based on the pre-fetched sender and relayer accounts, - * within the given context and world updater. - * - * @param sender the sender account - * @param relayer the relayer account - * @param context the context of the transaction, including the network gas price - * @param worldUpdater the world updater for the transaction - * @param transaction the transaction to charge gas for - * @return the result of the gas charging - * @throws HandleException if the gas charging fails fo - */ - public GasChargingResult tryToChargeGas( - @NonNull final HederaEvmAccount sender, - @Nullable final HederaEvmAccount relayer, - @NonNull final HederaEvmContext context, - @NonNull final HederaWorldUpdater worldUpdater, - @NonNull final HederaEvmTransaction transaction) { - throw new AssertionError("Not implemented"); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/GasChargingResult.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/GasChargingResult.java deleted file mode 100644 index c4f84d944c91..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/gas/GasChargingResult.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.gas; - -import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; - -public record GasChargingResult( - @NonNull HederaEvmAccount sender, @Nullable HederaEvmAccount relayer, long allowanceUsed) {} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/AbstractCustomCreateOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/AbstractCustomCreateOperation.java deleted file mode 100644 index 66e38eb4b4fb..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/AbstractCustomCreateOperation.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.ILLEGAL_STATE_CHANGE; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.code.CodeFactory; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.AbstractOperation; -import org.hyperledger.besu.evm.operation.Operation; - -/** - * Implementation assistance for Hedera-customized create operations. Specializations must override methods to: - *

    - *
  1. Check if the create operation is disabled.
  2. - *
  3. Compute the address for the new contract, and set up the create in the frame's {@link ProxyWorldUpdater}.
  4. - *
  5. Do any Hedera-specific completion work needed when the spawned {@code CONTRACT_CREATION} succeeds.
  6. - *
- * - *

Note that unlike in Besu, it is possible for the second step that computes the new address to fail, since - * a {@code CREATE2} could reference an existing hollow account with lazy creation disabled. So this class also does - * a null-check after calling {@link AbstractCustomCreateOperation#setupPendingCreation(MessageFrame)}, and fails - * as appropriate. - */ -public abstract class AbstractCustomCreateOperation extends AbstractOperation { - private static final int MAX_STACK_DEPTH = 1024; - private static final Operation.OperationResult INVALID_RESPONSE = - new OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION); - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - - protected AbstractCustomCreateOperation( - final int opcode, - @NonNull final String name, - final int stackItemsConsumed, - final int stackItemsProduced, - @NonNull final GasCalculator gasCalculator) { - super(opcode, name, stackItemsConsumed, stackItemsProduced, gasCalculator); - } - - /** - * Returns true if this operation is enabled for the given frame. - * - * @param frame the frame running the operation - * @return true if enabled - */ - protected abstract boolean isEnabled(@NonNull MessageFrame frame); - - /** - * Returns the gas cost of this operation for the given frame. - * - * @param frame the frame running the operation - * @return the gas cost - */ - protected abstract long cost(@NonNull MessageFrame frame); - - /** - * Sets up the pending creation for this operation and returns the address to be used - * as receiver of the child {@code CONTRACT_CREATION} message; or null if the creation - * should be aborted. - * - * @param frame the frame running the operation (and possibly spawning the child CONTRACT_CREATION) - * @return the address for the child message, or null if the creation should be aborted - */ - protected abstract @Nullable Address setupPendingCreation(@NonNull final MessageFrame frame); - - /** - * Called when the child {@code CONTRACT_CREATION} message has completed successfully, - * used to give specializations the chance to do any Hedera-specific logic. - * - * @param frame the frame running the successful operation - * @param createdAddress the address of the newly created contract - */ - protected abstract void onSuccess(@NonNull MessageFrame frame, @NonNull Address createdAddress); - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - if (!isEnabled(frame)) { - return INVALID_RESPONSE; - } - if (frame.stackSize() < getStackItemsConsumed()) { - return UNDERFLOW_RESPONSE; - } - final long cost = cost(frame); - if (frame.isStatic()) { - return new OperationResult(cost, ILLEGAL_STATE_CHANGE); - } - if (frame.getRemainingGas() < cost) { - return new Operation.OperationResult(cost, INSUFFICIENT_GAS); - } - final var value = Wei.wrap(frame.getStackItem(0)); - final var account = - frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getMutable(); - frame.clearReturnData(); - if (value.compareTo(account.getBalance()) > 0 || frame.getMessageStackDepth() >= MAX_STACK_DEPTH) { - fail(frame); - } else { - spawnChildMessage(frame); - } - return new Operation.OperationResult(cost, null); - } - - private void spawnChildMessage(@NonNull final MessageFrame frame) { - // Calculate memory cost prior to expansion - final var cost = cost(frame); - frame.decrementRemainingGas(cost); - - final var account = - frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getMutable(); - account.incrementNonce(); - - final var value = Wei.wrap(frame.getStackItem(0)); - final var inputOffset = clampedToLong(frame.getStackItem(1)); - final var inputSize = clampedToLong(frame.getStackItem(2)); - final var inputData = frame.readMemory(inputOffset, inputSize); - final var contractAddress = setupPendingCreation(frame); - - if (contractAddress == null) { - fail(frame); - return; - } - - final var childGasStipend = gasCalculator().gasAvailableForChildCreate(frame.getRemainingGas()); - frame.decrementRemainingGas(childGasStipend); - final var childFrame = MessageFrame.builder() - .type(MessageFrame.Type.CONTRACT_CREATION) - .messageFrameStack(frame.getMessageFrameStack()) - .worldUpdater(frame.getWorldUpdater().updater()) - .initialGas(childGasStipend) - .address(contractAddress) - .originator(frame.getOriginatorAddress()) - .contract(contractAddress) - .gasPrice(frame.getGasPrice()) - .inputData(Bytes.EMPTY) - .sender(frame.getRecipientAddress()) - .value(value) - .apparentValue(value) - .code(CodeFactory.createCode(inputData, 0, false)) - .blockValues(frame.getBlockValues()) - .depth(frame.getMessageStackDepth() + 1) - .completer(child -> complete(frame, child)) - .miningBeneficiary(frame.getMiningBeneficiary()) - .blockHashLookup(frame.getBlockHashLookup()) - .maxStackSize(frame.getMaxStackSize()) - .build(); - frame.incrementRemainingGas(cost); - frame.getMessageFrameStack().addFirst(childFrame); - frame.setState(MessageFrame.State.CODE_SUSPENDED); - } - - private void fail(@NonNull final MessageFrame frame) { - final var inputOffset = clampedToLong(frame.getStackItem(1)); - final var inputSize = clampedToLong(frame.getStackItem(2)); - frame.readMutableMemory(inputOffset, inputSize); - frame.popStackItems(getStackItemsConsumed()); - frame.pushStackItem(UInt256.ZERO); - } - - private void complete(@NonNull final MessageFrame frame, @NonNull final MessageFrame childFrame) { - frame.setState(MessageFrame.State.CODE_EXECUTING); - frame.incrementRemainingGas(childFrame.getRemainingGas()); - frame.addLogs(childFrame.getLogs()); - frame.addSelfDestructs(childFrame.getSelfDestructs()); - frame.incrementGasRefund(childFrame.getGasRefund()); - frame.popStackItems(getStackItemsConsumed()); - if (childFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { - frame.mergeWarmedUpFields(childFrame); - final var creation = childFrame.getContractAddress(); - frame.pushStackItem(Words.fromAddress(creation)); - onSuccess(frame, creation); - } else { - frame.setReturnData(childFrame.getOutputData()); - frame.pushStackItem(UInt256.ZERO); - } - final var currentPC = frame.getPC(); - frame.setPC(currentPC + 1); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomBalanceOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomBalanceOperation.java deleted file mode 100644 index 9223480abf31..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomBalanceOperation.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.BalanceOperation; - -public class CustomBalanceOperation extends BalanceOperation { - private final AddressChecks addressChecks; - - public CustomBalanceOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(gasCalculator); - this.addressChecks = addressChecks; - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var address = Words.toAddress(frame.getStackItem(0)); - // Make system contract balance invisible to EVM (added in v0.38) - if (addressChecks.isSystemAccount(address)) { - frame.popStackItem(); - frame.pushStackItem(UInt256.ZERO); - return new OperationResult(cost(true), null); - } - // Otherwise continue to enforce existence checks for backward compatibility - if (!addressChecks.isPresent(address, frame)) { - return new OperationResult(cost(true), CustomExceptionalHaltReason.MISSING_ADDRESS); - } - return super.execute(frame, evm); - } catch (FixedStack.UnderflowException ignore) { - return new OperationResult(cost(true), ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallCodeOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallCodeOperation.java deleted file mode 100644 index 3b671c692315..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallCodeOperation.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.spi.meta.bni.Dispatch; -import com.hedera.node.app.spi.meta.bni.VerificationStrategy; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.CallCodeOperation; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.processor.MessageCallProcessor; - -/** - * A small customization of the Besu {@link CallCodeOperation} that checks for missing - * addresses before delegating the call. - * - *

IMPORTANT: This operation no longer does checks for receiver signature - * requirements when value is being transferred; those requirements will be enforced in - * the call the {@link MessageCallProcessor} makes to {@link Dispatch#transferWithReceiverSigCheck(long, long, long, VerificationStrategy)}. - */ -public class CustomCallCodeOperation extends CallCodeOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - private final AddressChecks addressChecks; - - public CustomCallCodeOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(gasCalculator); - this.addressChecks = addressChecks; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallOperation.java deleted file mode 100644 index e0a8e9afc5d0..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCallOperation.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.isLongZero; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.spi.meta.bni.Dispatch; -import com.hedera.node.app.spi.meta.bni.VerificationStrategy; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.CallOperation; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.processor.MessageCallProcessor; - -/** - * A Hedera customization of {@link CallOperation} that, if lazy creation is enabled and - * applies to a call, does no additional address checks. Otherwise, only allows calls to an - * address that is either a Hedera precompile, a system address, or not missing. - * - *

IMPORTANT: This operation no longer enforces for receiver signature requirements - * when value is being transferred; that will now happen in the call the {@link MessageCallProcessor} - * makes to {@link Dispatch#transferWithReceiverSigCheck(long, long, long, VerificationStrategy)}. - */ -public class CustomCallOperation extends CallOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - - private final FeatureFlags featureFlags; - private final AddressChecks addressChecks; - - public CustomCallOperation( - @NonNull final FeatureFlags featureFlags, - @NonNull final GasCalculator gasCalculator, - @NonNull final AddressChecks addressChecks) { - super(gasCalculator); - this.featureFlags = Objects.requireNonNull(featureFlags); - this.addressChecks = Objects.requireNonNull(addressChecks); - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var toAddress = to(frame); - final var isMissing = mustBePresent(frame, toAddress) && !addressChecks.isPresent(toAddress, frame); - return isMissing ? new Operation.OperationResult(cost(frame), MISSING_ADDRESS) : super.execute(frame, evm); - } catch (final FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } - - private boolean mustBePresent(@NonNull final MessageFrame frame, @NonNull final Address toAddress) { - // This call will create the "to" address, so it doesn't need to be present - if (impliesLazyCreation(frame, toAddress) && featureFlags.isImplicitCreationEnabled(frame)) { - return false; - } - // Let system accounts through so the message call processor can fail in a more legible way - return !addressChecks.isSystemAccount(toAddress); - } - - private boolean impliesLazyCreation(@NonNull final MessageFrame frame, @NonNull final Address toAddress) { - return !isLongZero(toAddress) - && value(frame).greaterThan(Wei.ZERO) - && !addressChecks.isPresent(toAddress, frame); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomChainIdOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomChainIdOperation.java deleted file mode 100644 index 3f07ab20e36e..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomChainIdOperation.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.operations.CustomizedOpcodes.CHAINID; -import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.configOf; - -import com.hedera.node.config.data.ContractsConfig; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.AbstractOperation; - -/** - * A {@code CHAINID} operation that uses the {@link com.hedera.node.config.data.ContractsConfig} from the - * frame context variables to provide the chain id. (The - * {@link com.hedera.node.app.service.contract.impl.exec.TransactionProcessor} must always set - * the config in the frame context, since in principle it could vary with every transaction.) - */ -public class CustomChainIdOperation extends AbstractOperation { - private final long cost; - - public CustomChainIdOperation(@NonNull final GasCalculator gasCalculator) { - super(CHAINID.opcode(), "CHAINID", 0, 1, gasCalculator); - this.cost = Objects.requireNonNull(gasCalculator).getBaseTierGasCost(); - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - if (frame.getRemainingGas() < cost) { - return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS); - } - final var chainIdAsInt = - configOf(frame).getConfigData(ContractsConfig.class).chainId(); - final var chainId = Bytes32.fromHexStringLenient(Integer.toString(chainIdAsInt, 16)); - frame.pushStackItem(chainId); - return new OperationResult(cost, null); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreate2Operation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreate2Operation.java deleted file mode 100644 index 95f6c60ffddb..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreate2Operation.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.operations.CustomizedOpcodes.CREATE2; -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.bouncycastle.jcajce.provider.digest.Keccak; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; - -public class CustomCreate2Operation extends AbstractCustomCreateOperation { - private static final Bytes EIP_1014_PREFIX = Bytes.fromHexString("0xFF"); - private final FeatureFlags featureFlags; - - public CustomCreate2Operation( - @NonNull final GasCalculator gasCalculator, @NonNull final FeatureFlags featureFlags) { - super(CREATE2.opcode(), "ħCREATE2", 4, 1, gasCalculator); - this.featureFlags = featureFlags; - } - - @Override - protected boolean isEnabled(@NonNull final MessageFrame frame) { - return featureFlags.isCreate2Enabled(frame); - } - - @Override - protected long cost(@NonNull final MessageFrame frame) { - return gasCalculator().create2OperationGasCost(frame); - } - - @Override - protected @Nullable Address setupPendingCreation(@NonNull final MessageFrame frame) { - final var alias = eip1014AddressFor(frame); - final var updater = (ProxyWorldUpdater) frame.getWorldUpdater(); - // A bit arbitrary maybe, but if implicit creation isn't enabled, we also - // don't support finalizing hollow accounts as contracts, so return null - if (updater.isHollowAccount(alias) && !featureFlags.isImplicitCreationEnabled(frame)) { - return null; - } - updater.setupCreate2(frame.getRecipientAddress(), alias); - frame.warmUpAddress(alias); - return alias; - } - - @Override - protected void onSuccess(@NonNull final MessageFrame frame, @NonNull final Address creation) { - final var updater = (ProxyWorldUpdater) frame.getWorldUpdater(); - if (updater.isHollowAccount(creation)) { - updater.finalizeHollowAccount(creation); - } - } - - private Address eip1014AddressFor(@NonNull final MessageFrame frame) { - // If the recipient has an EIP-1014 address, it must have been used here - final var creatorAddress = frame.getRecipientAddress(); - final var offset = clampedToLong(frame.getStackItem(1)); - final var length = clampedToLong(frame.getStackItem(2)); - final Bytes32 salt = UInt256.fromBytes(frame.getStackItem(3)); - final var initCode = frame.readMutableMemory(offset, length); - final var hash = keccak256(Bytes.concatenate(EIP_1014_PREFIX, creatorAddress, salt, keccak256(initCode))); - return Address.wrap(hash.slice(12, 20)); - } - - private Bytes32 keccak256(final Bytes input) { - return Bytes32.wrap(keccak256DigestOf(input.toArrayUnsafe())); - } - - private static byte[] keccak256DigestOf(final byte[] msg) { - return new Keccak.Digest256().digest(msg); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreateOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreateOperation.java deleted file mode 100644 index 9f6413738984..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomCreateOperation.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.operations.CustomizedOpcodes.CREATE; - -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; - -public class CustomCreateOperation extends AbstractCustomCreateOperation { - public CustomCreateOperation(@NonNull final GasCalculator gasCalculator) { - super(CREATE.opcode(), "ħCREATE", 3, 1, gasCalculator); - } - - @Override - protected boolean isEnabled(@NonNull final MessageFrame frame) { - return true; - } - - @Override - protected void onSuccess(@NonNull final MessageFrame frame, @NonNull final Address createdAddress) { - // Nothing to do here, the record of the creation will be tracked as - // a side-effect of dispatching from ProxyWorldUpdater#createAccount() - } - - @Override - protected long cost(@NonNull final MessageFrame frame) { - return gasCalculator().createOperationGasCost(frame); - } - - @Override - protected @NonNull Address setupPendingCreation(@NonNull final MessageFrame frame) { - final var updater = (ProxyWorldUpdater) frame.getWorldUpdater(); - final var address = updater.setupCreate(frame.getRecipientAddress()); - frame.warmUpAddress(address); - return address; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomDelegateCallOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomDelegateCallOperation.java deleted file mode 100644 index 995994ded7d9..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomDelegateCallOperation.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.DelegateCallOperation; -import org.hyperledger.besu.evm.operation.Operation; - -/** - * A customization of the Besu {@link DelegateCallOperation} that checks for missing addresses before delegating the call. - */ -public class CustomDelegateCallOperation extends DelegateCallOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - private final AddressChecks addressChecks; - - public CustomDelegateCallOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(Objects.requireNonNull(gasCalculator)); - this.addressChecks = Objects.requireNonNull(addressChecks); - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var address = Words.toAddress(frame.getStackItem(0)); - if (addressChecks.isNeitherSystemNorPresent(address, frame)) { - return new OperationResult(cost(frame), MISSING_ADDRESS); - } - return super.execute(frame, evm); - } catch (FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeCopyOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeCopyOperation.java deleted file mode 100644 index ec8af70dad15..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeCopyOperation.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.ExtCodeCopyOperation; -import org.hyperledger.besu.evm.operation.Operation; - -/** - * Customization of {@link ExtCodeCopyOperation} that treats every long-zero address for an account - * below {@code 0.0.1001} as having zero code; and otherwise requires the account to be present or - * halts the frame with {@link CustomExceptionalHaltReason#MISSING_ADDRESS}. - */ -public class CustomExtCodeCopyOperation extends ExtCodeCopyOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - private final AddressChecks addressChecks; - - public CustomExtCodeCopyOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(gasCalculator); - this.addressChecks = addressChecks; - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var address = Words.toAddress(frame.getStackItem(0)); - final var memOffset = clampedToLong(frame.getStackItem(1)); - final var sourceOffset = clampedToLong(frame.getStackItem(2)); - final var numBytes = clampedToLong(frame.getStackItem(3)); - // Special behavior for long-zero addresses below 0.0.1001 - if (addressChecks.isNonUserAccount(address)) { - frame.writeMemory(memOffset, sourceOffset, numBytes, Bytes.EMPTY); - frame.popStackItems(4); - return new OperationResult(cost(frame, memOffset, numBytes, true), null); - } - // Otherwise the address must be present - if (!addressChecks.isPresent(address, frame)) { - return new OperationResult(cost(frame, memOffset, numBytes, true), MISSING_ADDRESS); - } - return super.execute(frame, evm); - } catch (FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeHashOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeHashOperation.java deleted file mode 100644 index 700013944cb0..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeHashOperation.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.ExtCodeHashOperation; -import org.hyperledger.besu.evm.operation.Operation; - -/** - * Customization of {@link ExtCodeHashOperation} that treats every long-zero address for an account - * below {@code 0.0.1001} as having a zero code hash; and otherwise requires the account to be - * present or halts the frame with {@link CustomExceptionalHaltReason#MISSING_ADDRESS}. - */ -public class CustomExtCodeHashOperation extends ExtCodeHashOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - private final AddressChecks addressChecks; - - public CustomExtCodeHashOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(Objects.requireNonNull(gasCalculator)); - this.addressChecks = Objects.requireNonNull(addressChecks); - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var address = Words.toAddress(frame.getStackItem(0)); - // Special behavior for long-zero addresses below 0.0.1001 - if (addressChecks.isNonUserAccount(address)) { - frame.popStackItem(); - frame.pushStackItem(UInt256.ZERO); - return new OperationResult(cost(true), null); - } - // Otherwise the address must be present - if (!addressChecks.isPresent(address, frame)) { - return new OperationResult(cost(true), MISSING_ADDRESS); - } - return super.execute(frame, evm); - } catch (FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeSizeOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeSizeOperation.java deleted file mode 100644 index bb3e04c54aa0..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomExtCodeSizeOperation.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Objects; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.ExtCodeSizeOperation; -import org.hyperledger.besu.evm.operation.Operation; - -public class CustomExtCodeSizeOperation extends ExtCodeSizeOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - private final AddressChecks addressChecks; - - public CustomExtCodeSizeOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(Objects.requireNonNull(gasCalculator)); - this.addressChecks = Objects.requireNonNull(addressChecks); - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var address = Words.toAddress(frame.getStackItem(0)); - // Special behavior for long-zero addresses below 0.0.1001 - if (addressChecks.isNonUserAccount(address)) { - frame.popStackItem(); - frame.pushStackItem(UInt256.ZERO); - return new OperationResult(cost(true), null); - } - if (!addressChecks.isPresent(address, frame)) { - return new OperationResult(cost(true), MISSING_ADDRESS); - } - return super.execute(frame, evm); - } catch (FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomSelfDestructOperation.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomSelfDestructOperation.java deleted file mode 100644 index 4816d6ed0f55..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomSelfDestructOperation.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.exec.operations.CustomizedOpcodes.SELFDESTRUCT; -import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.isDelegateCall; -import static java.util.Objects.requireNonNull; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.ILLEGAL_STATE_CHANGE; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import com.hedera.node.app.spi.meta.bni.VerificationStrategy; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.AbstractOperation; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.SelfDestructOperation; - -/** - * Hedera {@link SelfDestructOperation} that checks whether there is a Hedera-specific reason to halt - * execution before proceeding with a self-destruct that uses - * {@link com.hedera.node.app.spi.meta.bni.Dispatch#transferWithReceiverSigCheck(long, long, long, VerificationStrategy)}. - * instead of direct {@link org.hyperledger.besu.evm.account.MutableAccount#setBalance(Wei)} calls to - * ensure Hedera signing requirements are enforced. - */ -public class CustomSelfDestructOperation extends AbstractOperation { - private static final Operation.OperationResult UNDERFLOW_RESPONSE = - new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - - private final AddressChecks addressChecks; - - public CustomSelfDestructOperation( - @NonNull final GasCalculator gasCalculator, @NonNull final AddressChecks addressChecks) { - super(SELFDESTRUCT.opcode(), "SELFDESTRUCT", 1, 0, gasCalculator); - this.addressChecks = addressChecks; - } - - @Override - public OperationResult execute(@NonNull final MessageFrame frame, @NonNull final EVM evm) { - try { - final var beneficiaryAddress = Words.toAddress(frame.popStackItem()); - // Enforce Hedera-specific checks on the beneficiary address - if (addressChecks.isSystemAccount(beneficiaryAddress) - || !addressChecks.isPresent(beneficiaryAddress, frame)) { - return haltFor(null, 0, MISSING_ADDRESS); - } - - final var tbdAddress = frame.getRecipientAddress(); - final var proxyWorldUpdater = (ProxyWorldUpdater) frame.getWorldUpdater(); - // Enforce Hedera-specific restrictions on account deletion - final var maybeHaltReason = proxyWorldUpdater.tryTrackingDeletion(tbdAddress, beneficiaryAddress); - if (maybeHaltReason.isPresent()) { - return haltFor(null, 0, maybeHaltReason.get()); - } - - // Now proceed with the self-destruct - final var inheritance = - requireNonNull(proxyWorldUpdater.get(tbdAddress)).getBalance(); - final var beneficiary = proxyWorldUpdater.get(beneficiaryAddress); - final var beneficiaryIsWarm = - frame.warmUpAddress(beneficiaryAddress) || gasCalculator().isPrecompile(beneficiaryAddress); - final var cost = gasCalculator().selfDestructOperationGasCost(beneficiary, inheritance) - + (beneficiaryIsWarm ? 0L : gasCalculator().getColdAccountAccessCost()); - if (frame.isStatic()) { - return new OperationResult(cost, ILLEGAL_STATE_CHANGE); - } else if (frame.getRemainingGas() < cost) { - return new OperationResult(cost, INSUFFICIENT_GAS); - } - - // This will enforce the Hedera signing requirements (while treating any Key{contractID=tbdAddress} - // or Key{delegatable_contract_id=tbdAddress} keys on the beneficiary account as active); it could - // also fail if the beneficiary is a token address - final var maybeReasonToHalt = proxyWorldUpdater.tryTransferFromContract( - tbdAddress, beneficiaryAddress, inheritance.toLong(), isDelegateCall(frame)); - if (maybeReasonToHalt.isPresent()) { - return new OperationResult(cost, maybeReasonToHalt.get()); - } - frame.addSelfDestruct(tbdAddress); - frame.addRefund(beneficiaryAddress, inheritance); - frame.setState(MessageFrame.State.CODE_SUCCESS); - return new OperationResult(cost, null); - } catch (FixedStack.UnderflowException ignore) { - return UNDERFLOW_RESPONSE; - } - } - - private OperationResult haltFor( - @Nullable final Account beneficiary, final long inheritance, @NonNull final ExceptionalHaltReason reason) { - final long cost = gasCalculator().selfDestructOperationGasCost(beneficiary, Wei.of(inheritance)); - return new OperationResult(cost, reason); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomizedOpcodes.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomizedOpcodes.java deleted file mode 100644 index 723d532ed9a3..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/operations/CustomizedOpcodes.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.operations; - -/** - * A few opcodes that need more-than-usual customization in the Hedera EVM and thus - * don't even inherit the corresponding Besu operation, instead directly overriding - * {@link org.hyperledger.besu.evm.operation.AbstractOperation} themselves. - * - *

Please see here - * for a review of the EVM opcodes. - */ -public enum CustomizedOpcodes { - CHAINID(0x46), - CREATE(0xf0), - CREATE2(0xf5), - SELFDESTRUCT(0xff); - - CustomizedOpcodes(int opcode) { - this.opcode = opcode; - } - - public int opcode() { - return opcode; - } - - private final int opcode; -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomContractCreationProcessor.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomContractCreationProcessor.java deleted file mode 100644 index c6dc99c270a6..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomContractCreationProcessor.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.processors; - -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.List; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; - -public class CustomContractCreationProcessor extends ContractCreationProcessor { - public CustomContractCreationProcessor( - @NonNull final EVM evm, - @NonNull final GasCalculator gasCalculator, - final boolean requireCodeDepositToSucceed, - @NonNull final List contractValidationRules, - final long initialContractNonce) { - super(gasCalculator, evm, requireCodeDepositToSucceed, contractValidationRules, initialContractNonce); - } -} 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 deleted file mode 100644 index b9f0ef1e7f4b..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.processors; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_VALUE_TRANSFER; -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.isDelegateCall; -import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.transfersValue; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.PRECOMPILE_ERROR; -import static org.hyperledger.besu.evm.frame.MessageFrame.State.EXCEPTIONAL_HALT; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.processor.MessageCallProcessor; -import org.hyperledger.besu.evm.tracing.OperationTracer; - -/** - * A {@link MessageCallProcessor} customized to, - *

    - *
  1. Call Hedera-specific precompiles.
  2. - *
  3. Impose Hedera restrictions in the system account range.
  4. - *
  5. Do lazy creation when appropriate.
  6. - *
- * Note these only require changing {@link MessageCallProcessor#start(MessageFrame, OperationTracer)}, - * and the core {@link MessageCallProcessor#process(MessageFrame, OperationTracer)} logic we inherit. - */ -public class CustomMessageCallProcessor extends MessageCallProcessor { - private final FeatureFlags featureFlags; - private final AddressChecks addressChecks; - private final PrecompileContractRegistry precompiles; - private final Map hederaPrecompiles; - - public CustomMessageCallProcessor( - @NonNull final EVM evm, - @NonNull final FeatureFlags featureFlags, - @NonNull final PrecompileContractRegistry precompiles, - @NonNull final AddressChecks addressChecks, - @NonNull final Map hederaPrecompiles) { - super(evm, precompiles); - this.featureFlags = Objects.requireNonNull(featureFlags); - this.precompiles = Objects.requireNonNull(precompiles); - this.addressChecks = Objects.requireNonNull(addressChecks); - this.hederaPrecompiles = Objects.requireNonNull(hederaPrecompiles); - } - - /** - * Starts the execution of a message call based on the contract address of the given frame, - * or halts the frame with an appropriate reason if this cannot be done. - * - *

This contract address may reference, - *

    - *
  1. A Hedera precompile.
  2. - *
  3. A native EVM precompile.
  4. - *
  5. A Hedera system account (up to {@code 0.0.750}).
  6. - *
  7. A valid lazy-creation target address.
  8. - *
  9. An existing contract.
  10. - *
  11. An existing account.
  12. - *
- * - * @param frame the frame to start - * @param tracer the operation tracer - */ - @Override - public void start(@NonNull final MessageFrame frame, @NonNull final OperationTracer tracer) { - final var codeAddress = frame.getContractAddress(); - if (hederaPrecompiles.containsKey(codeAddress)) { - throw new UnsupportedOperationException("Hedera precompiles"); - } else if (addressChecks.isSystemAccount(codeAddress)) { - doHaltIfInvalidSystemCall(codeAddress, frame, tracer); - } else if (transfersValue(frame)) { - doTransferValueOrHalt(frame, tracer); - } - if (!alreadyHalted(frame)) { - final var evmPrecompile = precompiles.get(codeAddress); - if (evmPrecompile != null) { - doExecute(evmPrecompile, frame, tracer); - } else { - frame.setState(MessageFrame.State.CODE_EXECUTING); - } - } - } - - public boolean isImplicitCreationEnabled(@NonNull Configuration config) { - return featureFlags.isImplicitCreationEnabled(config); - } - - private void doExecute( - @NonNull final PrecompiledContract precompile, - @NonNull final MessageFrame frame, - @NonNull final OperationTracer tracer) { - final var gasRequirement = precompile.gasRequirement(frame.getInputData()); - if (frame.getRemainingGas() < gasRequirement) { - doHalt(frame, INSUFFICIENT_GAS); - } else { - frame.decrementRemainingGas(gasRequirement); - final var result = precompile.computePrecompile(frame.getInputData(), frame); - tracer.tracePrecompileCall(frame, gasRequirement, result.getOutput()); - if (result.isRefundGas()) { - frame.incrementRemainingGas(gasRequirement); - } - if (frame.getState() == MessageFrame.State.REVERT) { - frame.setRevertReason(result.getOutput()); - } else { - frame.setOutputData(result.getOutput()); - } - frame.setState(result.getState()); - frame.setExceptionalHaltReason(result.getHaltReason()); - } - } - - private void doTransferValueOrHalt( - @NonNull final MessageFrame frame, @NonNull final OperationTracer operationTracer) { - final var proxyWorldUpdater = (ProxyWorldUpdater) frame.getWorldUpdater(); - // Lazy-create the recipient address if it doesn't exist - if (!addressChecks.isPresent(frame.getRecipientAddress(), frame)) { - final var maybeReasonToHalt = proxyWorldUpdater.tryLazyCreation(frame.getRecipientAddress(), frame); - maybeReasonToHalt.ifPresent(reason -> doHalt(frame, reason, operationTracer)); - } - if (!alreadyHalted(frame)) { - final var maybeReasonToHalt = proxyWorldUpdater.tryTransferFromContract( - frame.getSenderAddress(), - frame.getRecipientAddress(), - frame.getValue().toLong(), - isDelegateCall(frame)); - maybeReasonToHalt.ifPresent(reason -> doHalt(frame, reason, operationTracer)); - } - } - - private void doHaltIfInvalidSystemCall( - @NonNull final Address codeAddress, - @NonNull final MessageFrame frame, - @NonNull final OperationTracer operationTracer) { - if (precompiles.get(codeAddress) == null) { - doHalt(frame, PRECOMPILE_ERROR, operationTracer); - } else if (transfersValue(frame)) { - doHalt(frame, INVALID_VALUE_TRANSFER, operationTracer); - } - } - - private void doHalt(@NonNull final MessageFrame frame, @NonNull final ExceptionalHaltReason reason) { - doHalt(frame, reason, null); - } - - private void doHalt( - @NonNull final MessageFrame frame, - @NonNull final ExceptionalHaltReason reason, - @Nullable final OperationTracer operationTracer) { - frame.setState(EXCEPTIONAL_HALT); - frame.setExceptionalHaltReason(Optional.of(reason)); - if (operationTracer != null) { - operationTracer.tracePostExecution(frame, new Operation.OperationResult(frame.getRemainingGas(), reason)); - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/ProcessorModule.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/ProcessorModule.java deleted file mode 100644 index 99469ce2efa2..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/processors/ProcessorModule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.processors; - -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.IntoSet; -import javax.inject.Singleton; -import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; -import org.hyperledger.besu.evm.contractvalidation.MaxCodeSizeRule; -import org.hyperledger.besu.evm.contractvalidation.PrefixCodeRule; - -@Module -public interface ProcessorModule { - long INITIAL_CONTRACT_NONCE = 1L; - boolean REQUIRE_CODE_DEPOSIT_TO_SUCCEED = true; - - @Provides - @Singleton - @IntoSet - static ContractValidationRule provideMaxCodeSizeRule() { - return MaxCodeSizeRule.of(0x6000); - } - - @Provides - @Singleton - @IntoSet - static ContractValidationRule providePrefixCodeRule() { - return PrefixCodeRule.of(); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/FrameUtils.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/FrameUtils.java deleted file mode 100644 index 5de18850eefe..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/utils/FrameUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.utils; - -import static com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.CONFIG_CONTEXT_VARIABLE; -import static java.util.Objects.requireNonNull; - -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.function.Predicate; -import org.hyperledger.besu.evm.frame.MessageFrame; - -public class FrameUtils { - public static @NonNull Configuration configOf(@NonNull final MessageFrame frame) { - return requireNonNull(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)); - } - - public static boolean testConfigOf( - @NonNull final MessageFrame frame, @NonNull final Predicate test) { - return test.test(configOf(frame)); - } - - public static boolean isDelegateCall(@NonNull final MessageFrame frame) { - return !frame.getRecipientAddress().equals(frame.getContractAddress()); - } - - public static boolean transfersValue(@NonNull final MessageFrame frame) { - return !frame.getValue().isZero(); - } - - public static boolean alreadyHalted(@NonNull final MessageFrame frame) { - return frame.getState() == MessageFrame.State.EXCEPTIONAL_HALT; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/V030Module.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/V030Module.java deleted file mode 100644 index 22e8569dfb61..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/V030Module.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v030; - -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.INITIAL_CONTRACT_NONCE; -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.REQUIRE_CODE_DEPOSIT_TO_SUCCEED; -import static org.hyperledger.besu.evm.MainnetEVMs.registerLondonOperations; - -import com.hedera.node.app.service.contract.impl.annotations.ServicesV030; -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomBalanceOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCallOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomChainIdOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreate2Operation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreateOperation; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomContractCreationProcessor; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import dagger.Binds; -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.IntoSet; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.math.BigInteger; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.EvmSpecVersion; -import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.OperationRegistry; -import org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts; -import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; - -/** - * Provides the Services 0.30 EVM implementation, which consists of London operations and - * Instanbul precompiles plus the Hedera gas calculator, system contracts, and operations - * as they were configured in the 0.30 release (in particular, without lazy creation and - * without special treatment to make system addresses "invisible"). - */ -@Module -public interface V030Module { - @Provides - @Singleton - @ServicesV030 - static TransactionProcessor provideTransactionProcessor( - @ServicesV030 @NonNull final CustomMessageCallProcessor messageCallProcessor, - @ServicesV030 @NonNull final ContractCreationProcessor contractCreationProcessor, - @NonNull final GasCalculator gasCalculator) { - return new TransactionProcessor(gasCalculator, messageCallProcessor, contractCreationProcessor); - } - - @Provides - @Singleton - @ServicesV030 - static ContractCreationProcessor provideContractCreationProcessor( - @ServicesV030 @NonNull final EVM evm, - @NonNull final GasCalculator gasCalculator, - @NonNull final Set validationRules) { - return new CustomContractCreationProcessor( - evm, - gasCalculator, - REQUIRE_CODE_DEPOSIT_TO_SUCCEED, - List.copyOf(validationRules), - INITIAL_CONTRACT_NONCE); - } - - @Provides - @Singleton - @ServicesV030 - static CustomMessageCallProcessor provideMessageCallProcessor( - @ServicesV030 @NonNull final EVM evm, - @ServicesV030 @NonNull final FeatureFlags featureFlags, - @ServicesV030 @NonNull final AddressChecks addressChecks, - @ServicesV030 @NonNull final PrecompileContractRegistry registry, - @NonNull final Map hederaPrecompiles) { - return new CustomMessageCallProcessor(evm, featureFlags, registry, addressChecks, hederaPrecompiles); - } - - @Provides - @Singleton - @ServicesV030 - static EVM provideEVM( - @ServicesV030 @NonNull final Set customOperations, @NonNull final GasCalculator gasCalculator) { - // Use London EVM with 0.30 custom operations and 0x00 chain id (set at runtime) - final var operationRegistry = new OperationRegistry(); - registerLondonOperations(operationRegistry, gasCalculator, BigInteger.ZERO); - customOperations.forEach(operationRegistry::put); - return new EVM(operationRegistry, gasCalculator, EvmConfiguration.DEFAULT, EvmSpecVersion.LONDON); - } - - @Provides - @Singleton - @ServicesV030 - static PrecompileContractRegistry providePrecompileContractRegistry(@NonNull final GasCalculator gasCalculator) { - final var precompileContractRegistry = new PrecompileContractRegistry(); - MainnetPrecompiledContracts.populateForIstanbul(precompileContractRegistry, gasCalculator); - return precompileContractRegistry; - } - - @Binds - @ServicesV030 - FeatureFlags bindFeatureFlags(Version030FeatureFlags featureFlags); - - @Binds - @ServicesV030 - AddressChecks bindAddressChecks(Version030AddressChecks addressChecks); - - @Provides - @IntoSet - @ServicesV030 - static Operation provideBalanceOperation( - @NonNull final GasCalculator gasCalculator, @ServicesV030 @NonNull final AddressChecks addressChecks) { - return new CustomBalanceOperation(gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV030 - static Operation provideChainIdOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomChainIdOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV030 - static Operation provideCallOperation( - @NonNull final GasCalculator gasCalculator, - @ServicesV030 @NonNull final FeatureFlags featureFlags, - @ServicesV030 @NonNull final AddressChecks addressChecks) { - return new CustomCallOperation(featureFlags, gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV030 - static Operation provideCreateOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomCreateOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV030 - static Operation provideCreate2Operation( - @NonNull final GasCalculator gasCalculator, @ServicesV030 @NonNull final FeatureFlags featureFlags) { - return new CustomCreate2Operation(gasCalculator, featureFlags); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030AddressChecks.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030AddressChecks.java deleted file mode 100644 index 204bc08430ca..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030AddressChecks.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v030; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; - -/** - * The initial implementation of {@link AddressChecks} from v0.30; did not have a concept of system accounts. - */ -@Singleton -public class Version030AddressChecks implements AddressChecks { - private final int[] precompileAccountNumbers; - - @Inject - public Version030AddressChecks(@NonNull final Map hederaPrecompiles) { - precompileAccountNumbers = new int[hederaPrecompiles.size()]; - int i = 0; - for (final var address : hederaPrecompiles.keySet()) { - if (address.numberOfLeadingZeroBytes() != 18) { - throw new IllegalArgumentException("Precompile address " + address + " is outside system range"); - } - precompileAccountNumbers[i++] = address.getInt(16); - } - } - - @Override - public boolean isPresent(@NonNull final Address address, @NonNull final MessageFrame frame) { - return isHederaPrecompile(address) || frame.getWorldUpdater().get(address) != null; - } - - @Override - public boolean isSystemAccount(@NonNull final Address address) { - return false; - } - - @Override - public boolean isNonUserAccount(@NonNull final Address address) { - return false; - } - - @Override - public boolean isHederaPrecompile(@NonNull final Address address) { - return address.numberOfLeadingZeroBytes() >= 18 && isPrecompile(address.getInt(16)); - } - - private boolean isPrecompile(final int number) { - for (final var precompileNumber : precompileAccountNumbers) { - if (precompileNumber == number) { - return true; - } - } - return false; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030FeatureFlags.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030FeatureFlags.java deleted file mode 100644 index 4dea345bcd2b..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v030/Version030FeatureFlags.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v030; - -import static com.hedera.node.app.service.contract.impl.exec.utils.FrameUtils.configOf; - -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.config.data.ContractsConfig; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.hyperledger.besu.evm.frame.MessageFrame; - -/** - * The initial implementation of {@link FeatureFlags} from v0.30; lazy creation never enabled - * but {@code CREATE2} still with a feature flag. - */ -@Singleton -public class Version030FeatureFlags implements FeatureFlags { - @Inject - public Version030FeatureFlags() { - // Dagger2 - } - - @Override - public boolean isCreate2Enabled(@NonNull final MessageFrame frame) { - return configOf(frame).getConfigData(ContractsConfig.class).allowCreate2(); - } - - @Override - public boolean isImplicitCreationEnabled(@NonNull Configuration config) { - return false; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/V034Module.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/V034Module.java deleted file mode 100644 index 931cdf1ff5a0..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/V034Module.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v034; - -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.INITIAL_CONTRACT_NONCE; -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.REQUIRE_CODE_DEPOSIT_TO_SUCCEED; -import static org.hyperledger.besu.evm.MainnetEVMs.registerLondonOperations; - -import com.hedera.node.app.service.contract.impl.annotations.ServicesV034; -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomBalanceOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCallOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomChainIdOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreate2Operation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreateOperation; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomContractCreationProcessor; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import com.hedera.node.app.service.contract.impl.exec.v030.Version030AddressChecks; -import dagger.Binds; -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.IntoSet; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.math.BigInteger; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.EvmSpecVersion; -import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.OperationRegistry; -import org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts; -import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; - -/** - * Provides the Services 0.34 EVM implementation, which consists of Paris operations and - * Instanbul precompiles plus the Hedera gas calculator, system contracts, and operations - * as they were configured in the 0.34 release (in particular, with the option for lazy - * creation, but without special treatment for system addresses). - */ -@Module -public interface V034Module { - @Provides - @Singleton - @ServicesV034 - static TransactionProcessor provideTransactionProcessor( - @ServicesV034 @NonNull final CustomMessageCallProcessor messageCallProcessor, - @ServicesV034 @NonNull final ContractCreationProcessor contractCreationProcessor, - @NonNull final GasCalculator gasCalculator) { - return new TransactionProcessor(gasCalculator, messageCallProcessor, contractCreationProcessor); - } - - @Provides - @Singleton - @ServicesV034 - static ContractCreationProcessor provideContractCreationProcessor( - @ServicesV034 @NonNull final EVM evm, - @NonNull final GasCalculator gasCalculator, - @NonNull final Set validationRules) { - return new CustomContractCreationProcessor( - evm, - gasCalculator, - REQUIRE_CODE_DEPOSIT_TO_SUCCEED, - List.copyOf(validationRules), - INITIAL_CONTRACT_NONCE); - } - - @Provides - @Singleton - @ServicesV034 - static CustomMessageCallProcessor provideMessageCallProcessor( - @ServicesV034 @NonNull final EVM evm, - @ServicesV034 @NonNull final FeatureFlags featureFlags, - @ServicesV034 @NonNull final AddressChecks addressChecks, - @ServicesV034 @NonNull final PrecompileContractRegistry registry, - @NonNull final Map hederaPrecompiles) { - return new CustomMessageCallProcessor(evm, featureFlags, registry, addressChecks, hederaPrecompiles); - } - - @Provides - @Singleton - @ServicesV034 - static EVM provideEVM( - @ServicesV034 @NonNull final Set customOperations, @NonNull final GasCalculator gasCalculator) { - // Use Paris EVM with 0.34 custom operations and 0x00 chain id (set at runtime) - final var operationRegistry = new OperationRegistry(); - registerLondonOperations(operationRegistry, gasCalculator, BigInteger.ZERO); - customOperations.forEach(operationRegistry::put); - return new EVM(operationRegistry, gasCalculator, EvmConfiguration.DEFAULT, EvmSpecVersion.PARIS); - } - - @Provides - @Singleton - @ServicesV034 - static PrecompileContractRegistry providePrecompileContractRegistry(@NonNull final GasCalculator gasCalculator) { - final var precompileContractRegistry = new PrecompileContractRegistry(); - MainnetPrecompiledContracts.populateForIstanbul(precompileContractRegistry, gasCalculator); - return precompileContractRegistry; - } - - @Binds - @ServicesV034 - FeatureFlags bindFeatureFlags(Version034FeatureFlags featureFlags); - - @Binds - @ServicesV034 - AddressChecks bindAddressChecks(Version030AddressChecks addressChecks); - - @Provides - @IntoSet - @ServicesV034 - static Operation provideBalanceOperation( - @NonNull final GasCalculator gasCalculator, @ServicesV034 @NonNull final AddressChecks addressChecks) { - return new CustomBalanceOperation(gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV034 - static Operation provideChainIdOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomChainIdOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV034 - static Operation provideCallOperation( - @NonNull final GasCalculator gasCalculator, - @ServicesV034 @NonNull final FeatureFlags featureFlags, - @ServicesV034 @NonNull final AddressChecks addressChecks) { - return new CustomCallOperation(featureFlags, gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV034 - static Operation provideCreateOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomCreateOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV034 - static Operation provideCreate2Operation( - @NonNull final GasCalculator gasCalculator, @ServicesV034 @NonNull final FeatureFlags featureFlags) { - return new CustomCreate2Operation(gasCalculator, featureFlags); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/Version034FeatureFlags.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/Version034FeatureFlags.java deleted file mode 100644 index bab09ce82248..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v034/Version034FeatureFlags.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v034; - -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.v030.Version030FeatureFlags; -import com.hedera.node.config.data.AutoCreationConfig; -import com.hedera.node.config.data.LazyCreationConfig; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * The v0.34+ implementation of {@link FeatureFlags}; lazy creation enabled if config says so. - */ -@Singleton -public class Version034FeatureFlags extends Version030FeatureFlags { - @Inject - public Version034FeatureFlags() { - // Dagger2 - } - - @Override - public boolean isImplicitCreationEnabled(@NonNull final Configuration config) { - return config.getConfigData(AutoCreationConfig.class).enabled() - && config.getConfigData(LazyCreationConfig.class).enabled(); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/V038Module.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/V038Module.java deleted file mode 100644 index d2132ba1daf1..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/V038Module.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v038; - -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.INITIAL_CONTRACT_NONCE; -import static com.hedera.node.app.service.contract.impl.exec.processors.ProcessorModule.REQUIRE_CODE_DEPOSIT_TO_SUCCEED; -import static org.hyperledger.besu.evm.MainnetEVMs.registerShanghaiOperations; - -import com.hedera.node.app.service.contract.impl.annotations.ServicesV038; -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomBalanceOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCallOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomChainIdOperation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreate2Operation; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreateOperation; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomContractCreationProcessor; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import com.hedera.node.app.service.contract.impl.exec.v034.Version034FeatureFlags; -import dagger.Binds; -import dagger.Module; -import dagger.Provides; -import dagger.multibindings.IntoSet; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.math.BigInteger; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.EvmSpecVersion; -import org.hyperledger.besu.evm.contractvalidation.ContractValidationRule; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.operation.OperationRegistry; -import org.hyperledger.besu.evm.precompile.MainnetPrecompiledContracts; -import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; - -/** - * Provides the Services 0.38 EVM implementation, which consists of Shanghai operations and - * Instanbul precompiles plus the Hedera gas calculator, system contracts, and operations - * as they were configured in the 0.38 release (with both the option for lazy creation, and - * with special treatment to treat system addresses in a more legible way across a few types - * of operations). - */ -@Module -public interface V038Module { - @Provides - @Singleton - @ServicesV038 - static TransactionProcessor provideTransactionProcessor( - @ServicesV038 @NonNull final CustomMessageCallProcessor messageCallProcessor, - @ServicesV038 @NonNull final ContractCreationProcessor contractCreationProcessor, - @NonNull final GasCalculator gasCalculator) { - return new TransactionProcessor(gasCalculator, messageCallProcessor, contractCreationProcessor); - } - - @Provides - @Singleton - @ServicesV038 - static ContractCreationProcessor provideContractCreationProcessor( - @ServicesV038 @NonNull final EVM evm, - @NonNull final GasCalculator gasCalculator, - @NonNull final Set validationRules) { - return new CustomContractCreationProcessor( - evm, - gasCalculator, - REQUIRE_CODE_DEPOSIT_TO_SUCCEED, - List.copyOf(validationRules), - INITIAL_CONTRACT_NONCE); - } - - @Provides - @Singleton - @ServicesV038 - static CustomMessageCallProcessor provideMessageCallProcessor( - @ServicesV038 @NonNull final EVM evm, - @ServicesV038 @NonNull final FeatureFlags featureFlags, - @ServicesV038 @NonNull final AddressChecks addressChecks, - @ServicesV038 @NonNull final PrecompileContractRegistry registry, - @NonNull final Map hederaPrecompiles) { - return new CustomMessageCallProcessor(evm, featureFlags, registry, addressChecks, hederaPrecompiles); - } - - @Provides - @Singleton - @ServicesV038 - static EVM provideEVM( - @ServicesV038 @NonNull final Set customOperations, @NonNull final GasCalculator gasCalculator) { - // Use Paris EVM with 0.38 custom operations and 0x00 chain id (set at runtime) - final var operationRegistry = new OperationRegistry(); - registerShanghaiOperations(operationRegistry, gasCalculator, BigInteger.ZERO); - customOperations.forEach(operationRegistry::put); - return new EVM(operationRegistry, gasCalculator, EvmConfiguration.DEFAULT, EvmSpecVersion.SHANGHAI); - } - - @Provides - @Singleton - @ServicesV038 - static PrecompileContractRegistry providePrecompileContractRegistry(@NonNull final GasCalculator gasCalculator) { - final var precompileContractRegistry = new PrecompileContractRegistry(); - MainnetPrecompiledContracts.populateForIstanbul(precompileContractRegistry, gasCalculator); - return precompileContractRegistry; - } - - @Binds - @ServicesV038 - FeatureFlags bindFeatureFlags(Version034FeatureFlags featureFlags); - - @Binds - @ServicesV038 - AddressChecks bindAddressChecks(Version038AddressChecks addressChecks); - - @Provides - @IntoSet - @ServicesV038 - static Operation provideBalanceOperation( - @NonNull final GasCalculator gasCalculator, @ServicesV038 @NonNull final AddressChecks addressChecks) { - return new CustomBalanceOperation(gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV038 - static Operation provideChainIdOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomChainIdOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV038 - static Operation provideCallOperation( - @NonNull final GasCalculator gasCalculator, - @ServicesV038 @NonNull final FeatureFlags featureFlags, - @ServicesV038 @NonNull final AddressChecks addressChecks) { - return new CustomCallOperation(featureFlags, gasCalculator, addressChecks); - } - - @Provides - @IntoSet - @ServicesV038 - static Operation provideCreateOperation(@NonNull final GasCalculator gasCalculator) { - return new CustomCreateOperation(gasCalculator); - } - - @Provides - @IntoSet - @ServicesV038 - static Operation provideCreate2Operation( - @NonNull final GasCalculator gasCalculator, @ServicesV038 @NonNull final FeatureFlags featureFlags) { - return new CustomCreate2Operation(gasCalculator, featureFlags); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/Version038AddressChecks.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/Version038AddressChecks.java deleted file mode 100644 index 9e3aa2d3f9b8..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/exec/v038/Version038AddressChecks.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.exec.v038; - -import com.hedera.node.app.service.contract.impl.exec.v030.Version030AddressChecks; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; - -/** - * The system-aware address checks for the 0.38+, which customize some {@link Operation} and - * {@link AbstractMessageProcessor} behavior to treat system addresses below 0.0.750 as special. - */ -@Singleton -public class Version038AddressChecks extends Version030AddressChecks { - private static final int NUM_SYSTEM_ACCOUNTS = 750; - private static final int FIRST_USER_ACCOUNT = 1_001; - - @Inject - public Version038AddressChecks(@NonNull Map hederaPrecompiles) { - super(hederaPrecompiles); - } - - @Override - public boolean isSystemAccount(@NonNull final Address address) { - return address.numberOfLeadingZeroBytes() >= 18 && address.getInt(16) <= NUM_SYSTEM_ACCOUNTS; - } - - @Override - public boolean isNonUserAccount(@NonNull final Address address) { - return address.numberOfLeadingZeroBytes() >= 18 && address.getInt(16) < FIRST_USER_ACCOUNT; - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmBlocks.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmBlocks.java deleted file mode 100644 index 4e9fa3550389..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmBlocks.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -import com.hedera.node.app.service.evm.contracts.execution.BlockMetaSource; -import com.hedera.node.app.service.evm.contracts.execution.HederaEvmTxProcessor; -import com.swirlds.common.crypto.DigestType; -import com.swirlds.common.crypto.ImmutableHash; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.evm.frame.BlockValues; - -/** - * Provides block information as context for a {@link HederaEvmTxProcessor}. - */ -public interface HederaEvmBlocks { - Hash UNAVAILABLE_BLOCK_HASH = besuHashFrom(new ImmutableHash(new byte[DigestType.SHA_384.digestLength()])); - - /** - * Returns the hash of the given block number, or {@link BlockMetaSource#UNAVAILABLE_BLOCK_HASH} - * if unavailable. - * - * @param blockNo the block number of interest - * @return its hash, if available - */ - Hash blockHashOf(long blockNo); - - /** - * Returns the in-scope block values, given an effective gas limit. - * - * @param gasLimit the effective gas limit - * @return the scoped block values - */ - BlockValues blockValuesOf(long gasLimit); - - static Hash besuHashFrom(@NonNull final com.swirlds.common.crypto.Hash hash) { - final byte[] hashBytesToConvert = hash.getValue(); - final byte[] prefixBytes = new byte[32]; - System.arraycopy(hashBytesToConvert, 0, prefixBytes, 0, 32); - return org.hyperledger.besu.datatypes.Hash.wrap(Bytes32.wrap(prefixBytes)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmContext.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmContext.java deleted file mode 100644 index 3370ee82f5ad..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmContext.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -public record HederaEvmContext(long gasPrice, boolean staticCall, HederaEvmBlocks blocks) {} 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 deleted file mode 100644 index b089efb7850a..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransaction.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ContractID; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Objects; - -public record HederaEvmTransaction( - @NonNull AccountID senderId, - @Nullable AccountID relayerId, - @Nullable ContractID contractId, - long nonce, - @NonNull Bytes callData, - @Nullable Bytes chainId, - long value, - long gasLimit, - long offeredGasPrice, - long maxGasAllowance) { - public boolean isCreate() { - return contractId == null; - } - - public @NonNull ContractID contractIdOrThrow() { - return Objects.requireNonNull(contractId); - } - - public boolean hasValue() { - return value > 0; - } - - public long upfrontCostGiven(final long gasPrice) { - try { - return Math.multiplyExact(gasLimit, gasPrice) + value; - } catch (Exception ignore) { - return Long.MAX_VALUE; - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionProcessor.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionProcessor.java deleted file mode 100644 index 5bcf59fe00e1..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionProcessor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -import static java.util.Objects.requireNonNull; - -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.hyperledger.besu.evm.tracing.OperationTracer; - -@Singleton -public class HederaEvmTransactionProcessor { - private final Map transactionProcessors; - - @Inject - public HederaEvmTransactionProcessor( - @NonNull final Map transactionProcessors) { - this.transactionProcessors = requireNonNull(transactionProcessors); - } - - public HederaEvmTransactionResult process( - @NonNull final HederaEvmTransaction transaction, - @NonNull final HederaWorldUpdater worldUpdater, - @NonNull final HederaEvmContext context, - @NonNull final HederaEvmVersion version, - @NonNull final OperationTracer tracer, - @NonNull final Configuration config) { - return requireNonNull(transactionProcessors.get(version)) - .processTransaction( - requireNonNull(transaction), - requireNonNull(worldUpdater), - requireNonNull(context), - requireNonNull(tracer), - requireNonNull(config)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionResult.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionResult.java deleted file mode 100644 index 91e04c034962..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaEvmTransactionResult.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -import static java.util.Objects.requireNonNull; - -import com.hedera.hapi.node.base.ResponseCodeEnum; -import com.hedera.hapi.node.contract.ContractLoginfo; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.List; - -public record HederaEvmTransactionResult( - long gasUsed, - long gasPrice, - @Nullable Bytes recipient, - @NonNull Bytes output, - @Nullable Bytes haltReason, - @Nullable ResponseCodeEnum abortReason, - @Nullable Bytes revertReason, - @NonNull List logs) { - public HederaEvmTransactionResult { - requireNonNull(output); - requireNonNull(logs); - } - - /** - * Create a result for a transaction that was aborted before entering the EVM due to a - * Hedera-specific reason. - * - * @param reason the reason for the abort - * @return the result - */ - public static HederaEvmTransactionResult abortFor(@NonNull final ResponseCodeEnum reason) { - return new HederaEvmTransactionResult(0, 0, null, Bytes.EMPTY, null, reason, null, List.of()); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaWorldUpdater.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaWorldUpdater.java deleted file mode 100644 index 3922377a745f..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/hevm/HederaWorldUpdater.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.hevm; - -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ContractID; -import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import com.hedera.node.app.service.contract.impl.state.PendingCreation; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.util.Optional; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; - -/** - * A {@link WorldUpdater} extension with additional methods for Hedera-specific operations. - */ -public interface HederaWorldUpdater extends WorldUpdater { - /** - * Returns the {@link HederaEvmAccount} for the given account id, or null if no - * such account (or contract). - * - * @param accountId the id of the account to get - * @return the account, or null if no such account - */ - @Nullable - HederaEvmAccount getHederaAccount(@NonNull AccountID accountId); - - /** - * Returns the {@link HederaEvmAccount} for the given contract id, or null if no - * such contract (or account). - * - * @param contractId the id of the contract to get - * @return the account, or null if no such account - */ - @Nullable - HederaEvmAccount getHederaAccount(@NonNull ContractID contractId); - - /** - * Collects the given fee from the given account. The caller should have already - * verified that the account exists and has sufficient balance to pay the fee, so - * this method surfaces any problem by throwing an exception. - * - * @param payer the account to collect the fee from - * @param amount the amount to collect - * @throws IllegalArgumentException if the collection fails for any reason - */ - void collectFee(@NonNull Address payer, long amount); - - /** - * Refunds the given fee to the given account. The caller should have already - * verified that the account exists, so this method surfaces any problem by - * throwing an exception. - * - * @param payer the account to refund the fee to - * @param amount the amount to refund - */ - void refundFee(@NonNull Address payer, long amount); - - /** - * Tries to transfer the given amount from a sending contract to the recipient. The sender - * has already authorized this action, in the sense that it is the address that has initiated - * either a message call with value or a {@code selfdestruct}. The recipient, however, must - * still be checked for authorization based on the Hedera concept of receiver signature - * requirements. - * - *

Returns true if the receiver authorization and transfer succeeded, false otherwise. - * - * @param sendingContract the sender of the transfer, already authorized - * @param recipient the recipient of the transfer, not yet authorized - * @param amount the amount to transfer - * @param delegateCall whether this transfer is done via code executed by a delegate call - * @return a optional with the reason to halt if the transfer failed, or empty if it succeeded - */ - Optional tryTransferFromContract( - @NonNull Address sendingContract, @NonNull Address recipient, long amount, boolean delegateCall); - - /** - * Attempts to lazy-create the account at the given address and decrement the gas remaining in the frame - * (since lazy creation has significant gas costs above the standard EVM fee schedule). - * - * @param recipient the address of the account to create - * @param frame the frame in which the account is being created - * @return an optional with the reason to halt if the creation failed, or empty if it succeeded - */ - Optional tryLazyCreation(@NonNull Address recipient, @NonNull MessageFrame frame); - - /** - * Attempts to track the given deletion of an account with the designated beneficiary, returning an optional - * {@link ExceptionalHaltReason} to indicate whether the deletion could be successfully tracked. - * - * @param deleted the address of the account being deleted - * @param beneficiary the address of the beneficiary of the deletion - * @return an optional {@link ExceptionalHaltReason} with the reason deletion could not be tracked - */ - Optional tryTrackingDeletion(@NonNull Address deleted, @NonNull Address beneficiary); - - /** - * Given the possibly zero address of the recipient of a {@code CONTRACT_CREATION} message, - * sets up the {@link PendingCreation} this {@link ProxyWorldUpdater} will use to complete - * the creation of the new account in {@link ProxyWorldUpdater#createAccount(Address, long, Wei)}; - * returns the "long-zero" address to be assigned to the new account. - * - * @param receiver the address of the recipient of a {@code CONTRACT_CREATION} message, zero if a top-level message - * @return the "long-zero" address to be assigned to the new account - */ - Address setupCreate(@NonNull Address receiver); - - /** - * Given the possibly zero address of the recipient of a {@code CONTRACT_CREATION} message, - * and the EIP-1014 address computed by an in-progress {@code CREATE2} operation, sets up the - * {@link PendingCreation} this {@link ProxyWorldUpdater} will use to complete the creation of - * the new account in {@link ProxyWorldUpdater#createAccount(Address, long, Wei)}. - * - *

Does not return anything, as the {@code CREATE2} address is already known. - * - * @param receiver the address of the recipient of a {@code CONTRACT_CREATION} message, zero if a top-level message - * @param alias the EIP-1014 address computed by an in-progress {@code CREATE2} operation - */ - void setupCreate2(@NonNull Address receiver, @NonNull Address alias); - - /** - * Returns whether this address refers to a hollow account (i.e. a lazy-created account that - * has not yet been completed as either an EOA with a cryptographic key, or a contract created - * with CREATE2.) - * - * @param address the address to check - * @return whether the address refers to a hollow account - */ - boolean isHollowAccount(@NonNull Address address); - - /** - * Finalizes the creation of a hollow account as a contract created via CREATE2. This step doesn't - * exist in Besu because there contracts are just normal accounts with code; but in Hedera, there - * are a few other properties that need to be set to "convert" an account into a contract. - * - * @param alias the hollow account to be finalized as a contract - */ - void finalizeHollowAccount(@NonNull Address alias); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/AbstractMutableEvmAccount.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/AbstractMutableEvmAccount.java index 96b505c46439..3dd0b5ee0379 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/AbstractMutableEvmAccount.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/AbstractMutableEvmAccount.java @@ -42,7 +42,7 @@ *

  • {@link MutableAccount#getUpdatedStorage()} - The {@link EvmFrameState} manages transaction boundaries.
  • * */ -public abstract class AbstractMutableEvmAccount implements MutableAccount, EvmAccount, HederaEvmAccount { +public abstract class AbstractMutableEvmAccount implements MutableAccount, EvmAccount { /** * Unlike in Besu, we don't store the address hash in state (c.f. {@link Account#getAddressHash()} javadoc); * and also don't support {@link org.hyperledger.besu.evm.worldstate.WorldState#streamAccounts(Bytes32, int)}. So @@ -69,7 +69,7 @@ public NavigableMap storageEntriesFrom(Bytes32 sta /** * Besu uses this method to do zero-sum balance changes, but since the {@link ContractService} neither * owns account state nor is aware of receiver signature requirements, it's more sensible to require - * message call processors to use {@link Dispatch#transferWithReceiverSigCheck(long, long, long, VerificationStrategy)}. + * message call processors to use {@link Dispatch#transferValue(long, long, long, VerificationStrategy)}. * * @param value the amount to set * @throws UnsupportedOperationException always diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/BaseProxyWorldUpdater.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/BaseProxyWorldUpdater.java index 56535f7cbb85..b5a0863d16cb 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/BaseProxyWorldUpdater.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/BaseProxyWorldUpdater.java @@ -16,7 +16,7 @@ package com.hedera.node.app.service.contract.impl.state; -import static com.hedera.node.app.service.contract.impl.state.ContractSchema.STORAGE_KEY; +import static com.hedera.node.app.service.contract.impl.ContractServiceImpl.STORAGE_KEY; import com.hedera.hapi.node.state.contract.SlotKey; import com.hedera.hapi.node.state.contract.SlotValue; diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ContractSchema.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ContractSchema.java deleted file mode 100644 index 9bc080d06b88..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ContractSchema.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.state; - -import com.hedera.hapi.node.base.SemanticVersion; -import com.hedera.hapi.node.state.common.EntityNumber; -import com.hedera.hapi.node.state.contract.Bytecode; -import com.hedera.hapi.node.state.contract.SlotKey; -import com.hedera.hapi.node.state.contract.SlotValue; -import com.hedera.node.app.spi.state.Schema; -import com.hedera.node.app.spi.state.StateDefinition; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Set; - -/** - * Defines the schema for the contract service's state. - */ -public class ContractSchema extends Schema { - public static final String STORAGE_KEY = "STORAGE"; - public static final String BYTECODE_KEY = "BYTECODE"; - private static final int MAX_BYTECODES = 50_000_000; - private static final int MAX_STORAGE_ENTRIES = 500_000_000; - private static final SemanticVersion CURRENT_VERSION = - SemanticVersion.newBuilder().minor(40).build(); - - public ContractSchema() { - super(CURRENT_VERSION); - } - - @NonNull - @Override - @SuppressWarnings("rawtypes") - public Set statesToCreate() { - return Set.of(storageDef(), bytecodeDef()); - } - - private @NonNull StateDefinition storageDef() { - return StateDefinition.onDisk(STORAGE_KEY, SlotKey.PROTOBUF, SlotValue.PROTOBUF, MAX_STORAGE_ENTRIES); - } - - private @NonNull StateDefinition bytecodeDef() { - return StateDefinition.onDisk(BYTECODE_KEY, EntityNumber.PROTOBUF, Bytecode.PROTOBUF, MAX_BYTECODES); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/DispatchingEvmFrameState.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/DispatchingEvmFrameState.java index 5aed4e586839..2e0fc2069ab2 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/DispatchingEvmFrameState.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/DispatchingEvmFrameState.java @@ -16,44 +16,26 @@ package com.hedera.node.app.service.contract.impl.state; -import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_SIGNATURE; -import static com.hedera.hapi.node.base.ResponseCodeEnum.MAX_CHILD_RECORDS_EXCEEDED; -import static com.hedera.hapi.node.base.ResponseCodeEnum.MAX_ENTITIES_IN_PRICE_REGIME_HAVE_BEEN_CREATED; -import static com.hedera.hapi.node.base.ResponseCodeEnum.OK; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.ACCOUNTS_LIMIT_REACHED; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_RECEIVER_SIGNATURE; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_VALUE_TRANSFER; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.SELFDESTRUCT_TO_SELF; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.TOKEN_HOLDER_SELFDESTRUCT; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.TOKEN_TREASURY_SELFDESTRUCT; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.TOO_MANY_CHILD_RECORDS; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.EVM_ADDRESS_LENGTH_AS_LONG; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.MISSING_ENTITY_NUMBER; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asLongZeroAddress; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.isLongZero; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.maybeMissingNumberOf; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToBesuAddress; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToTuweniBytes; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToTuweniUInt256; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.tuweniToPbjBytes; import static java.util.Objects.requireNonNull; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.ILLEGAL_STATE_CHANGE; -import com.hedera.hapi.node.base.Key; -import com.hedera.hapi.node.base.KeyList; import com.hedera.hapi.node.state.common.EntityNumber; import com.hedera.hapi.node.state.contract.Bytecode; import com.hedera.hapi.node.state.contract.SlotKey; import com.hedera.hapi.node.state.contract.SlotValue; -import com.hedera.node.app.spi.meta.bni.ActiveContractVerificationStrategy; +import com.hedera.node.app.service.contract.impl.utils.ConversionUtils; import com.hedera.node.app.spi.meta.bni.Dispatch; import com.hedera.node.app.spi.meta.bni.Scope; import com.hedera.node.app.spi.state.WritableKVState; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; -import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.hyperledger.besu.datatypes.Address; @@ -62,7 +44,6 @@ import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.EvmAccount; import org.hyperledger.besu.evm.code.CodeFactory; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; /** * An implementation of {@link EvmFrameState} that uses {@link WritableKVState}s to manage @@ -72,12 +53,10 @@ *

    Almost every access requires a conversion from a PBJ type to a Besu type. At some * point it might be necessary to cache the converted values and invalidate them when * the state changes. - *

    + * * TODO - get a little further to clarify DI strategy, then bring back a code cache. */ public class DispatchingEvmFrameState implements EvmFrameState { - private static final Key HOLLOW_ACCOUNT_KEY = - Key.newBuilder().keyList(KeyList.DEFAULT).build(); private static final String TOKEN_BYTECODE_PATTERN = "fefefefefefefefefefefefefefefefefefefefe"; @SuppressWarnings("java:S6418") @@ -176,21 +155,6 @@ public long getNonce(final long number) { return validatedAccount(number).ethereumNonce(); } - @Override - public int getNumTreasuryTitles(final long number) { - return validatedAccount(number).numberTreasuryTitles(); - } - - @Override - public boolean isContract(final long number) { - return validatedAccount(number).smartContract(); - } - - @Override - public int getNumPositiveTokenBalances(final long number) { - return validatedAccount(number).numberPositiveBalances(); - } - @Override public void setCode(final long number, @NonNull final Bytes code) { bytecode.put(new EntityNumber(number), new Bytecode(tuweniToPbjBytes(requireNonNull(code)))); @@ -212,9 +176,6 @@ public Wei getBalance(long number) { @Override public Address getAddress(final long number) { final var account = validatedAccount(number); - if (account.deleted()) { - return null; - } final var alias = account.alias(); if (alias.length() == EVM_ADDRESS_LENGTH_AS_LONG) { return pbjToBesuAddress(alias); @@ -223,150 +184,6 @@ public Address getAddress(final long number) { } } - @Override - public boolean isHollowAccount(@NonNull final Address address) { - final var number = maybeMissingNumberOf(address, dispatch); - if (number == MISSING_ENTITY_NUMBER) { - return false; - } - final var account = dispatch.getAccount(number); - if (account == null) { - return false; - } - return HOLLOW_ACCOUNT_KEY.equals(account.key()); - } - - /** - * {@inheritDoc} - */ - @Override - public void finalizeHollowAccount(@NonNull final Address address) { - dispatch.finalizeHollowAccountAsContract(tuweniToPbjBytes(address)); - } - - /** - * {@inheritDoc} - */ - @Override - public void collectFee(@NonNull final Address payer, final long amount) { - final var number = maybeMissingNumberOf(payer, dispatch); - if (number == MISSING_ENTITY_NUMBER) { - throw new IllegalArgumentException("Cannot collect fee from missing account " + payer); - } - dispatch.collectFee(number, amount); - } - - /** - * {@inheritDoc} - */ - @Override - public void refundFee(@NonNull final Address payer, final long amount) { - final var number = maybeMissingNumberOf(payer, dispatch); - if (number == MISSING_ENTITY_NUMBER) { - throw new IllegalArgumentException("Cannot refund fee to missing account " + payer); - } - dispatch.refundFee(number, amount); - } - - /** - * {@inheritDoc} - */ - @Override - public Optional tryTransferFromContract( - @NonNull final Address sendingContract, - @NonNull final Address recipient, - final long amount, - final boolean delegateCall) { - final var from = (ProxyEvmAccount) getAccount(sendingContract); - if (from == null) { - return Optional.of(MISSING_ADDRESS); - } - if (!from.isContract()) { - throw new IllegalArgumentException("EVM should not initiate transfer from EOA 0.0." + from.number); - } - final var to = getAccount(recipient); - if (to == null) { - return Optional.of(MISSING_ADDRESS); - } else if (to instanceof TokenEvmAccount) { - return Optional.of(ILLEGAL_STATE_CHANGE); - } - final var status = dispatch.transferWithReceiverSigCheck( - amount, - from.number, - ((ProxyEvmAccount) to).number, - new ActiveContractVerificationStrategy(from.number, tuweniToPbjBytes(from.getAddress()), delegateCall)); - if (status != OK) { - if (status == INVALID_SIGNATURE) { - return Optional.of(INVALID_RECEIVER_SIGNATURE); - } else { - throw new IllegalStateException("Transfer from 0.0." + from.number - + " to 0.0." + ((ProxyEvmAccount) to).number - + " failed with status " + status + " despite valid preconditions"); - } - } else { - return Optional.empty(); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Optional tryLazyCreation(@NonNull final Address address) { - if (isLongZero(address)) { - throw new IllegalArgumentException("Cannot perform lazy creation at long-zero address " + address); - } - final var number = maybeMissingNumberOf(address, dispatch); - if (number != MISSING_ENTITY_NUMBER) { - final var account = dispatch.getAccount(number); - if (account != null) { - if (account.expiredAndPendingRemoval()) { - return Optional.of(INVALID_VALUE_TRANSFER); - } else { - throw new IllegalArgumentException( - "Unexpired account 0.0." + number + " already exists at address " + address); - } - } - } - final var status = dispatch.createHollowAccount(tuweniToPbjBytes(address)); - if (status != OK) { - if (status == MAX_CHILD_RECORDS_EXCEEDED) { - return Optional.of(TOO_MANY_CHILD_RECORDS); - } else if (status == MAX_ENTITIES_IN_PRICE_REGIME_HAVE_BEEN_CREATED) { - return Optional.of(ACCOUNTS_LIMIT_REACHED); - } else { - throw new IllegalStateException( - "Lazy creation of account at address " + address + " failed with unexpected status " + status); - } - } - return Optional.empty(); - } - - /** - * {@inheritDoc} - */ - @Override - public Optional tryTrackingDeletion( - @NonNull final Address deleted, @NonNull final Address beneficiary) { - if (deleted.equals(beneficiary)) { - return Optional.of(SELFDESTRUCT_TO_SELF); - } - final var beneficiaryAccount = getAccount(beneficiary); - if (beneficiaryAccount == null || beneficiaryAccount instanceof TokenEvmAccount) { - return Optional.of(MISSING_ADDRESS); - } - // Token addresses don't have bytecode that could run a selfdestruct, so this cast is safe - final var deletedAccount = (ProxyEvmAccount) requireNonNull(getAccount(deleted)); - if (deletedAccount.numTreasuryTitles() > 0) { - return Optional.of(TOKEN_TREASURY_SELFDESTRUCT); - } - if (deletedAccount.numPositiveTokenBalances() > 0) { - return Optional.of(TOKEN_HOLDER_SELFDESTRUCT); - } - dispatch.trackDeletion(deletedAccount.number, ((ProxyEvmAccount) beneficiaryAccount).number); - return Optional.empty(); - } - /** * {@inheritDoc} */ @@ -380,7 +197,7 @@ public Optional tryTrackingDeletion( */ @Override public @Nullable EvmAccount getMutableAccount(@NonNull final Address address) { - final var number = maybeMissingNumberOf(address, dispatch); + final var number = ConversionUtils.maybeMissingNumberOf(address, dispatch); if (number == MISSING_ENTITY_NUMBER) { return null; } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/EvmFrameState.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/EvmFrameState.java index 465369b75107..8152ac4249dc 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/EvmFrameState.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/EvmFrameState.java @@ -16,12 +16,11 @@ package com.hedera.node.app.service.contract.impl.state; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCallOperation; +import com.hedera.node.app.service.contract.impl.ContractServiceImpl; import com.hedera.node.app.spi.meta.bni.Scope; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; -import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.hyperledger.besu.datatypes.Address; @@ -29,7 +28,6 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.EvmAccount; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; /** * Exposes the full Hedera state that may be read and changed directly from an EVM frame, @@ -52,92 +50,10 @@ public interface EvmFrameState { static EvmFrameState from(@NonNull final Scope scope) { return new DispatchingEvmFrameState( scope.dispatch(), - scope.writableContractState().get(ContractSchema.STORAGE_KEY), - scope.writableContractState().get(ContractSchema.BYTECODE_KEY)); + scope.writableContractState().get(ContractServiceImpl.STORAGE_KEY), + scope.writableContractState().get(ContractServiceImpl.BYTECODE_KEY)); } - /** - * Collects the given fee from the given account. The caller should have already - * verified that the account exists and has sufficient balance to pay the fee, so - * this method surfaces any problem by throwing an exception. - * - * @param payer the account to collect the fee from - * @param amount the amount to collect - * @throws IllegalArgumentException if the collection fails for any reason - */ - void collectFee(@NonNull Address payer, long amount); - - /** - * Refunds the given {@code amount} of fees from the given {@code fromEntityNumber}. - * - * @param payer the address of the account to refund the fees to - * @param amount the amount of fees to collect - */ - void refundFee(@NonNull Address payer, long amount); - - /** - * Tries to transfer the given amount from a sending contract to the recipient. The sender - * has already authorized this action, in the sense that it is the address that has initiated - * either a message call with value or a {@code selfdestruct}. The recipient, however, must - * still be checked for authorization based on the Hedera concept of receiver signature - * requirements. - * - *

    Returns true if the receiver authorization and transfer succeeded, false otherwise. - * - * @param sendingContract the sender of the transfer, already authorized - * @param recipient the recipient of the transfer, not yet authorized - * @param amount the amount to transfer - * @param delegateCall whether this transfer is done via code executed by a delegate call - * @return a optional with the reason to halt if the transfer failed, or empty if it succeeded - */ - Optional tryTransferFromContract( - @NonNull Address sendingContract, @NonNull Address recipient, long amount, boolean delegateCall); - - /** - * Tries to initialize a "lazy-created" account at the given address. The standard creation pattern for a - * Hedera account gives the account's key immediately. Lazy creation does not, instead initializing the - * account with just the EVM address derived from an ECDSA public key. - * - *

    Once we encounter a HAPI transaction with a full-prefix signature from this key, we can then finalize - * the account by giving it the full key. - * - *

    Lazy creation can fail for at least three reasons: - *

      - *
    1. There may be no more preceding child records available to externalize the creation.
    2. - *
    3. The Hedera accounts limit may be have been reached.
    4. - *
    5. There could already be an expired account at the given address.
    6. - *
    - * Note the {@link CustomCallOperation} will have already confirmed that the Hedera EVM in use supports - * lazy creation, and that it is enabled by properties. - * - * @param address the address of the account to try to lazy-create - * @return an optional {@link ExceptionalHaltReason} with the reason lazy creation could not be done - */ - Optional tryLazyCreation(@NonNull Address address); - - /** - * Returns whether the account with the given address is a "hollow account"; that is, an account - * created by a value transfer to a 20-byte alias, without an explicit cryptographic key given. - */ - boolean isHollowAccount(@NonNull Address address); - - /** - * Given an address that is a "hollow account", finalizes the account as a contract. - * - * @param address the address of the hollow account to finalize - */ - void finalizeHollowAccount(@NonNull Address address); - - /** - * Attempts to track the given deletion of an account with the designated beneficiary, returning an optional - * {@link ExceptionalHaltReason} to indicate whether the deletion could be successfully tracked. - * - * @param deleted the address of the account being deleted - * @param beneficiary the address of the beneficiary of the deletion - * @return an optional {@link ExceptionalHaltReason} with the reason deletion could not be tracked - */ - Optional tryTrackingDeletion(@NonNull Address deleted, @NonNull Address beneficiary); - /** * Returns the read-only account with the given address, or {@code null} if the account is missing, * deleted, or expired; or if this get() used the account's "long zero" address and not is priority @@ -221,30 +137,6 @@ Optional tryTransferFromContract( */ long getNonce(long number); - /** - * Returns the number of treasury titles for the account with the given number. - * - * @param number the account number - * @return the number of treasury titles - */ - int getNumTreasuryTitles(long number); - - /** - * Returns the number of positive token balances. - * - * @param number the account number - * @return the number of positive token balances - */ - int getNumPositiveTokenBalances(long number); - - /** - * Returns whether the account with the given number is a contract. - * - * @param number the account number - * @return whether the account is a contract - */ - boolean isContract(long number); - /** * Sets the nonce for the account with the given number. * diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/HederaEvmAccount.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/HederaEvmAccount.java deleted file mode 100644 index cd874cd3406d..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/HederaEvmAccount.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.state; - -import org.hyperledger.besu.evm.account.MutableAccount; - -public interface HederaEvmAccount extends MutableAccount { - /** - * Returns whether this account is an ERC-20/ERC-721 facade for a Hedera token. - * - * @return whether this account is token facade - */ - boolean isTokenFacade(); -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyEvmAccount.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyEvmAccount.java index 7e9df91e33a1..943e98eb1c91 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyEvmAccount.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyEvmAccount.java @@ -104,40 +104,4 @@ public void setCode(@NonNull final Bytes code) { public void setStorageValue(@NonNull final UInt256 key, @NonNull final UInt256 value) { state.setStorageValue(number, key, value); } - - // --- Hedera-specific methods --- - /** - * {@inheritDoc} - */ - @Override - public boolean isTokenFacade() { - return false; - } - - /** - * Returns the number of treasury titles held by this account. - * - * @return the number of treasury titles held by this account - */ - public int numTreasuryTitles() { - return state.getNumTreasuryTitles(number); - } - - /** - * Returns the number of positive token balances held by this account. - * - * @return the number of positive token balances held by this account - */ - public int numPositiveTokenBalances() { - return state.getNumPositiveTokenBalances(number); - } - - /** - * Returns whether the account is a contract. - * - * @return if the account is a contract - */ - public boolean isContract() { - return state.isContract(number); - } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyWorldUpdater.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyWorldUpdater.java index 5cfb621e8cd8..bd09b6bee198 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyWorldUpdater.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/ProxyWorldUpdater.java @@ -16,12 +16,14 @@ package com.hedera.node.app.service.contract.impl.state; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.*; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.MISSING_ENTITY_NUMBER; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.aliasFrom; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asLongZeroAddress; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.isLongZero; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.maybeMissingNumberOf; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.numberOfLongZero; import static java.util.Objects.requireNonNull; -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ContractID; -import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; import com.hedera.node.app.spi.meta.bni.Scope; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -33,8 +35,6 @@ import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; import org.hyperledger.besu.evm.account.EvmAccount; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.worldstate.WorldUpdater; /** @@ -49,7 +49,7 @@ *

    Note: The {@code sbhRefund} field in the {@code mono-service} {@link WorldUpdater} * hierarchy is---as best I can tell---now always zero. So it does not appear here. */ -public class ProxyWorldUpdater implements HederaWorldUpdater { +public class ProxyWorldUpdater implements WorldUpdater { private static final String CANNOT_CREATE = "Cannot create "; /** @@ -104,125 +104,49 @@ public ProxyWorldUpdater( this.evmFrameState = evmFrameStateFactory.createIn(scope); } - @Nullable - @Override - public HederaEvmAccount getHederaAccount(@NonNull AccountID accountId) { - final Address address; - if (accountId.hasAlias()) { - address = pbjToBesuAddress(accountId.aliasOrThrow()); - } else { - try { - address = evmFrameState.getAddress(accountId.accountNumOrElse(0L)); - } catch (IllegalArgumentException ignore) { - return null; - } - } - return address == null ? null : (HederaEvmAccount) get(address); - } - - @Nullable - @Override - public HederaEvmAccount getHederaAccount(@NonNull ContractID contractId) { - final Address address; - if (contractId.hasEvmAddress()) { - address = pbjToBesuAddress(contractId.evmAddressOrThrow()); - } else { - try { - address = evmFrameState.getAddress(contractId.contractNumOrElse(0L)); - } catch (IllegalArgumentException ignore) { - return null; - } - } - return address == null ? null : (HederaEvmAccount) get(address); - } - - @Override - public void collectFee(@NonNull final Address payer, final long amount) { - throw new AssertionError("Not implemented"); - } - - @Override - public void refundFee(@NonNull final Address payer, final long amount) { - throw new AssertionError("Not implemented"); - } - - /** - * {@inheritDoc} - */ - @Override - public Optional tryTransferFromContract( - @NonNull final Address sendingContract, - @NonNull final Address recipient, - final long amount, - final boolean delegateCall) { - return evmFrameState.tryTransferFromContract(sendingContract, recipient, amount, delegateCall); - } - /** * {@inheritDoc} */ @Override - public Optional tryLazyCreation( - @NonNull final Address recipient, @NonNull final MessageFrame frame) { - throw new AssertionError("Not implemented"); + public @Nullable Account get(@NonNull final Address address) { + return evmFrameState.getAccount(address); } /** * {@inheritDoc} */ @Override - public boolean isHollowAccount(@NonNull final Address address) { - return evmFrameState.isHollowAccount(address); + public EvmAccount getAccount(@NonNull final Address address) { + return evmFrameState.getMutableAccount(address); } /** - * {@inheritDoc} + * Given the possibly zero address of the recipient of a {@code CONTRACT_CREATION} message, + * sets up the {@link PendingCreation} this {@link ProxyWorldUpdater} will use to complete + * the creation of the new account in {@link ProxyWorldUpdater#createAccount(Address, long, Wei)}; + * returns the "long-zero" address to be assigned to the new account. + * + * @param origin the address of the recipient of a {@code CONTRACT_CREATION} message, zero if a top-level message + * @return the "long-zero" address to be assigned to the new account */ - @Override - public Address setupCreate(@NonNull final Address receiver) { - setupPendingCreation(receiver, null); + public Address setupCreate(@NonNull final Address origin) { + setupPendingCreation(origin, null); return requireNonNull(pendingCreation).address(); } /** - * {@inheritDoc} - */ - @Override - public void setupCreate2(@NonNull final Address receiver, @NonNull final Address alias) { - setupPendingCreation(receiver, alias); - } - - /** - * {@inheritDoc} - */ - @Override - public void finalizeHollowAccount(@NonNull final Address alias) { - evmFrameState.finalizeHollowAccount(alias); - } - - /** - * {@inheritDoc} - */ - @Override - public Optional tryTrackingDeletion( - @NonNull final Address deleted, @NonNull final Address beneficiary) { - throw new AssertionError("Not implemented"); - } - - /** - * {@inheritDoc} - */ - @Override - public @Nullable Account get(@NonNull final Address address) { - return evmFrameState.getAccount(address); - } - - /** - * {@inheritDoc} + * Given the possibly zero address of the recipient of a {@code CONTRACT_CREATION} message, + * and the EIP-1014 address computed by an in-progress {@code CREATE2} operation, sets up the + * {@link PendingCreation} this {@link ProxyWorldUpdater} will use to complete the creation of + * the new account in {@link ProxyWorldUpdater#createAccount(Address, long, Wei)}. + * + *

    Does not return anything, as the {@code CREATE2} address is already known. + * + * @param origin the address of the recipient of a {@code CONTRACT_CREATION} message, zero if a top-level message + * @param alias the EIP-1014 address computed by an in-progress {@code CREATE2} operation */ - @Override - public EvmAccount getAccount(@NonNull final Address address) { - return evmFrameState.getMutableAccount(address); + public void setupCreate2(@NonNull final Address origin, @NonNull final Address alias) { + setupPendingCreation(origin, alias); } /** @@ -294,9 +218,11 @@ public void commit() { * Returns the accounts that have been touched (i.e., created or maybe mutated but not deleted) * within the scope of this updater. * - *

    TODO - we may not need this; only used in Besu by - * {@code AbstractMessageProcessor.clearAccumulatedStateBesidesGasAndOutput()}, which seems to just deal - * with side-effects of an Ethereum consensus bug. + *

    We may not need this; only used in Besu by + * {@code AbstractMessageProcessor.clearAccumulatedStateBesidesGasAndOutput()}, which seems to be in + * response to unwinding side-effects of an Ethereum consensus bug. + * + *

    TODO - revisit whether this is needed. * * @return the accounts that have been touched */ @@ -338,13 +264,13 @@ private long getValidatedCreationNumber( return pendingNumber; } - private void setupPendingCreation(@NonNull final Address receiver, @Nullable final Address alias) { + private void setupPendingCreation(@NonNull final Address origin, @Nullable final Address alias) { final var number = scope.dispatch().peekNextEntityNumber(); - final long parentNumber = Address.ZERO.equals(requireNonNull(receiver)) + final long parentNumber = Address.ZERO.equals(requireNonNull(origin)) ? scope.payerAccountNumber() - : maybeMissingNumberOf(receiver, scope.dispatch()); + : maybeMissingNumberOf(origin, scope.dispatch()); if (parentNumber == MISSING_ENTITY_NUMBER) { - throw new IllegalStateException("Claimed receiver " + receiver + " has no Hedera account number"); + throw new IllegalStateException("Claimed origin " + origin + " has no Hedera account number"); } pendingCreation = new PendingCreation(alias == null ? asLongZeroAddress(number) : alias, number, parentNumber); } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/TokenEvmAccount.java b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/TokenEvmAccount.java index 8a1eb55a3169..c00a4d16eca6 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/TokenEvmAccount.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/main/java/com/hedera/node/app/service/contract/impl/state/TokenEvmAccount.java @@ -111,12 +111,4 @@ public void setCode(@NonNull final Bytes code) { public void setStorageValue(@NonNull final UInt256 key, @NonNull final UInt256 value) { throw new UnsupportedOperationException("setStorageValue"); } - - /** - * {@inheritDoc} - */ - @Override - public boolean isTokenFacade() { - return true; - } } 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 c2c501a1d58a..a2a4fc9a82a5 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 @@ -16,36 +16,18 @@ requires com.hedera.node.app.service.token; requires com.swirlds.jasperdb; requires static com.github.spotbugs.annotations; - requires org.bouncycastle.provider; provides com.hedera.node.app.service.contract.ContractService with ContractServiceImpl; - exports com.hedera.node.app.service.contract.impl; + exports com.hedera.node.app.service.contract.impl to + com.hedera.node.app, + com.hedera.node.app.service.contract.impl.test; exports com.hedera.node.app.service.contract.impl.handlers; - exports com.hedera.node.app.service.contract.impl.hevm; exports com.hedera.node.app.service.contract.impl.state to - com.hedera.node.app.service.contract.impl.test, - com.hedera.node.app; + com.hedera.node.app.service.contract.impl.test; exports com.hedera.node.app.service.contract.impl.utils to com.hedera.node.app.service.contract.impl.test; exports com.hedera.node.app.service.contract.impl.infra to com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.gas to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.v030 to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.utils to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.failure to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec; - exports com.hedera.node.app.service.contract.impl.exec.operations to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.processors to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.v034 to - com.hedera.node.app.service.contract.impl.test; - exports com.hedera.node.app.service.contract.impl.exec.v038 to - com.hedera.node.app.service.contract.impl.test; } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ContractServiceImplTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ContractServiceImplTest.java index 6235906da8e9..8abe461e1446 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ContractServiceImplTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ContractServiceImplTest.java @@ -17,16 +17,14 @@ package com.hedera.node.app.service.contract.impl.test; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.mockito.Mockito.verify; import com.hedera.node.app.service.contract.ContractService; import com.hedera.node.app.service.contract.impl.ContractServiceImpl; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionProcessor; -import com.hedera.node.app.service.contract.impl.state.ContractSchema; import com.hedera.node.app.spi.state.Schema; import com.hedera.node.app.spi.state.SchemaRegistry; import com.hedera.node.app.spi.state.StateDefinition; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -38,32 +36,34 @@ class ContractServiceImplTest { @Mock private SchemaRegistry registry; - private final ContractService subject = ContractService.getInstance(); - @Test void testSpi() { - assertInstanceOf(ContractServiceImpl.class, subject); + // when + final ContractService service = ContractService.getInstance(); + + // then + Assertions.assertNotNull(service, "We must always receive an instance"); + Assertions.assertEquals( + ContractServiceImpl.class, + service.getClass(), + "We must always receive an instance of type " + ContractServiceImpl.class.getName()); } @Test void registersExpectedSchema() { ArgumentCaptor schemaCaptor = ArgumentCaptor.forClass(Schema.class); + final var subject = ContractService.getInstance(); + subject.registerSchemas(registry); verify(registry).register(schemaCaptor.capture()); final var schema = schemaCaptor.getValue(); final var statesToCreate = schema.statesToCreate(); - assertEquals(2, statesToCreate.size()); + assertEquals(1, statesToCreate.size()); final var iter = statesToCreate.stream().map(StateDefinition::stateKey).sorted().iterator(); - assertEquals(ContractSchema.BYTECODE_KEY, iter.next()); - assertEquals(ContractSchema.STORAGE_KEY, iter.next()); - } - - @Test - void providesTransactionProcessor() { - assertInstanceOf(HederaEvmTransactionProcessor.class, ((ContractServiceImpl) subject).transactionProcessor()); + assertEquals(ContractServiceImpl.STORAGE_KEY, iter.next()); } } diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ServiceComponentTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ServiceComponentTest.java deleted file mode 100644 index 5a84e3d2f910..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/ServiceComponentTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test; - -import static org.junit.jupiter.api.Assertions.*; - -import com.hedera.node.app.service.contract.impl.DaggerServiceComponent; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionProcessor; -import org.junit.jupiter.api.Test; - -class ServiceComponentTest { - @Test - void objectRootsAreAvailable() { - final var subject = DaggerServiceComponent.create(); - - assertInstanceOf(HederaEvmTransactionProcessor.class, subject.transactionProcessor()); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/TestHelpers.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/TestHelpers.java deleted file mode 100644 index a67f18274430..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/TestHelpers.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test; - -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.tuweniToPbjBytes; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ContractID; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmBlocks; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmContext; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransaction; -import com.hedera.pbj.runtime.io.buffer.Bytes; -import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; -import java.math.BigInteger; -import java.util.Objects; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.operation.Operation; - -public class TestHelpers { - public static long REQUIRED_GAS = 123L; - public static long NONCE = 678; - public static long VALUE = 999_999; - public static long INTRINSIC_GAS = 12_345; - public static long GAS_LIMIT = 1_000_000; - public static long GAS_PRICE = 666; - public static long NETWORK_GAS_PRICE = 777; - public static long MAX_GAS_ALLOWANCE = 666_666_666; - public static Bytes CALL_DATA = Bytes.wrap(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}); - public static Bytes MAINNET_CHAIN_ID = Bytes.fromHex("0127"); - public static AccountID SENDER_ID = AccountID.newBuilder().accountNum(1234).build(); - public static AccountID RELAYER_ID = AccountID.newBuilder().accountNum(2345).build(); - public static ContractID CALLED_CONTRACT_ID = - ContractID.newBuilder().contractNum(666).build(); - public static Address SYSTEM_ADDRESS = - Address.fromHexString(BigInteger.valueOf(750).toString(16)); - public static Address HTS_PRECOMPILE_ADDRESS = Address.fromHexString("0x167"); - public static Address NON_SYSTEM_LONG_ZERO_ADDRESS = Address.fromHexString("0x1234576890"); - public static Address EIP_1014_ADDRESS = Address.fromHexString("0x89abcdef89abcdef89abcdef89abcdef89abcdef"); - public static ContractID CALLED_CONTRACT_EVM_ADDRESS = ContractID.newBuilder() - .evmAddress(tuweniToPbjBytes(EIP_1014_ADDRESS)) - .build(); - - public static void assertSameResult( - final Operation.OperationResult expected, final Operation.OperationResult actual) { - assertEquals(expected.getHaltReason(), actual.getHaltReason()); - assertEquals(expected.getGasCost(), actual.getGasCost()); - } - - public static boolean isSameResult( - final Operation.OperationResult expected, final Operation.OperationResult actual) { - return Objects.equals(expected.getHaltReason(), actual.getHaltReason()) - && expected.getGasCost() == actual.getGasCost(); - } - - public static HederaEvmTransaction wellKnownHapiCall() { - return wellKnownHapiCall(null, VALUE); - } - - public static HederaEvmTransaction wellKnownRelayedHapiCall(final long value) { - return wellKnownHapiCall(RELAYER_ID, value); - } - - public static HederaEvmTransaction wellKnownRelayedHapiCallWithGasLimit(final long gasLimit) { - return wellKnownHapiCall(RELAYER_ID, VALUE, gasLimit); - } - - public static HederaEvmTransaction wellKnownHapiCall(@Nullable final AccountID relayer, final long value) { - return wellKnownHapiCall(relayer, value, GAS_LIMIT); - } - - public static HederaEvmTransaction wellKnownHapiCall( - @Nullable final AccountID relayer, final long value, final long gasLimit) { - return new HederaEvmTransaction( - SENDER_ID, - relayer, - CALLED_CONTRACT_ID, - NONCE, - CALL_DATA, - MAINNET_CHAIN_ID, - value, - gasLimit, - GAS_PRICE, - MAX_GAS_ALLOWANCE); - } - - public static HederaEvmTransaction wellKnownLazyCreationWithGasLimit(final long gasLimit) { - return new HederaEvmTransaction( - SENDER_ID, - RELAYER_ID, - CALLED_CONTRACT_EVM_ADDRESS, - NONCE, - CALL_DATA, - MAINNET_CHAIN_ID, - VALUE, - gasLimit, - GAS_PRICE, - MAX_GAS_ALLOWANCE); - } - - public static HederaEvmContext wellKnownContextWith(@NonNull final HederaEvmBlocks blocks) { - return new HederaEvmContext(NETWORK_GAS_PRICE, false, blocks); - } - - public static HederaEvmContext wellKnownContextWith( - @NonNull final HederaEvmBlocks blocks, final boolean staticCall) { - return new HederaEvmContext(NETWORK_GAS_PRICE, staticCall, blocks); - } -} 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 deleted file mode 100644 index d447b77c3bfb..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/TransactionProcessorTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec; - -import static com.hedera.hapi.node.base.ResponseCodeEnum.*; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.BDDMockito.given; - -import com.hedera.hapi.node.base.ResponseCodeEnum; -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmBlocks; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransaction; -import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; -import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.processor.ContractCreationProcessor; -import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class TransactionProcessorTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private CustomMessageCallProcessor messageCallProcessor; - - @Mock - private ContractCreationProcessor contractCreationProcessor; - - @Mock - private HederaEvmBlocks blocks; - - @Mock - private HederaWorldUpdater worldUpdater; - - @Mock - private OperationTracer tracer; - - @Mock - private Configuration config; - - @Mock - private HederaEvmAccount senderAccount; - - @Mock - private HederaEvmAccount calledAccount; - - private TransactionProcessor subject; - - @BeforeEach - void setUp() { - subject = new TransactionProcessor(gasCalculator, messageCallProcessor, contractCreationProcessor); - } - - @Test - void abortsOnMissingSender() { - assertAbortsWith(INVALID_ACCOUNT_ID); - } - - @Test - void lazyCreationAttemptWithNoValueFailsFast() { - givenSenderAccount(); - given(messageCallProcessor.isImplicitCreationEnabled(config)).willReturn(true); - assertAbortsWith(wellKnownRelayedHapiCall(0), INVALID_CONTRACT_ID); - } - - private void assertAbortsWith(@NonNull final ResponseCodeEnum reason) { - assertAbortsWith(wellKnownHapiCall(), reason); - } - - private void assertAbortsWith( - @NonNull final HederaEvmTransaction transaction, @NonNull final ResponseCodeEnum reason) { - final var result = - subject.processTransaction(transaction, worldUpdater, wellKnownContextWith(blocks), tracer, config); - assertEquals(reason, result.abortReason()); - } - - private void givenSenderAccount() { - given(worldUpdater.getHederaAccount(SENDER_ID)).willReturn(senderAccount); - } - - private void givenSenderAccount(final long balance) { - given(worldUpdater.getHederaAccount(SENDER_ID)).willReturn(senderAccount); - given(senderAccount.getBalance()).willReturn(Wei.of(balance)); - } - - private void givenReceiverAccount() { - given(worldUpdater.getHederaAccount(CALLED_CONTRACT_ID)).willReturn(calledAccount); - } - - private void givenEvmReceiverAccount() { - given(worldUpdater.getHederaAccount(CALLED_CONTRACT_EVM_ADDRESS)).willReturn(calledAccount); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/gas/CustomGasChargingTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/gas/CustomGasChargingTest.java deleted file mode 100644 index 7a9aca20f144..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/gas/CustomGasChargingTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.gas; - -import com.hedera.node.app.service.contract.impl.exec.gas.CustomGasCharging; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmBlocks; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmContext; -import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; -import com.hedera.node.app.service.contract.impl.state.HederaEvmAccount; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomGasChargingTest { - @Mock - private HederaEvmAccount sender; - - @Mock - private HederaEvmAccount relayer; - - @Mock - private HederaEvmContext context; - - @Mock - private HederaEvmBlocks blocks; - - @Mock - private HederaWorldUpdater worldUpdater; - - @Mock - private GasCalculator gasCalculator; - - private CustomGasCharging subject; - - @BeforeEach - void setUp() { - subject = new CustomGasCharging(gasCalculator); - } - - @Test - void name() {} -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CreateOperationTestBase.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CreateOperationTestBase.java deleted file mode 100644 index 30eccf23abe2..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CreateOperationTestBase.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; - -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import java.util.Deque; -import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.EvmAccount; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.frame.BlockValues; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -public class CreateOperationTestBase { - protected static final long VALUE = 123_456L; - protected static final long GAS_COST = 1_234L; - protected static final long CHILD_STIPEND = 1_000_000L; - protected static final Wei GAS_PRICE = Wei.of(1000L); - protected static final Bytes INITCODE = Bytes.wrap(new byte[] {1, 2, 3, 4, 5}); - protected static final Address RECIEVER_ADDRESS = Address.BLAKE2B_F_COMPRESSION; - protected static final Address NEW_CONTRACT_ADDRESS = Address.BLS12_MAP_FP2_TO_G2; - protected static final Address ORIGINATOR_ADDRESS = Address.BLS12_G1ADD; - protected static final Address COINBASE_ADDRESS = Address.BLS12_G1MULTIEXP; - - @Mock - protected EVM evm; - - @Mock - protected BlockValues blockValues; - - @Mock - protected MessageFrame frame; - - @Mock - protected GasCalculator gasCalculator; - - @Mock - protected ProxyWorldUpdater worldUpdater; - - @Mock - protected EvmAccount receiver; - - @Mock - protected MutableAccount mutableReceiver; - - @Mock - protected Deque stack; - - protected void givenBuilderPrereqs() { - given(frame.getMessageFrameStack()).willReturn(stack); - given(worldUpdater.updater()).willReturn(worldUpdater); - given(gasCalculator.gasAvailableForChildCreate(anyLong())).willReturn(CHILD_STIPEND); - given(frame.getOriginatorAddress()).willReturn(ORIGINATOR_ADDRESS); - given(frame.getGasPrice()).willReturn(GAS_PRICE); - given(frame.getBlockValues()).willReturn(blockValues); - given(frame.getMiningBeneficiary()).willReturn(COINBASE_ADDRESS); - given(frame.getBlockHashLookup()).willReturn(l -> Hash.ZERO); - } - - protected void givenSpawnPrereqs() { - givenSpawnPrereqs(3); - } - - protected void givenSpawnPrereqs(final int stackSize) { - given(frame.stackSize()).willReturn(stackSize); - given(frame.getStackItem(anyInt())).willReturn(Bytes.ofUnsignedLong(1)); - given(frame.getRemainingGas()).willReturn(GAS_COST); - given(frame.getStackItem(0)).willReturn(Bytes.ofUnsignedLong(VALUE)); - given(frame.getRecipientAddress()).willReturn(RECIEVER_ADDRESS); - given(frame.getWorldUpdater()).willReturn(worldUpdater); - given(worldUpdater.getAccount(RECIEVER_ADDRESS)).willReturn(receiver); - given(receiver.getMutable()).willReturn(mutableReceiver); - given(mutableReceiver.getBalance()).willReturn(Wei.of(VALUE)); - given(frame.getMessageStackDepth()).willReturn(1023); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomBalanceOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomBalanceOperationTest.java deleted file mode 100644 index 0622531da122..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomBalanceOperationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.NON_SYSTEM_LONG_ZERO_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SYSTEM_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomBalanceOperation; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomBalanceOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private EVM evm; - - private CustomBalanceOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomBalanceOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - setupWarmGasCost(); - given(frame.getStackItem(0)).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(3L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - final var actual = subject.execute(frame, evm); - assertSameResult(expected, actual); - } - - @Test - void systemAccountBalanceHardCodedToZero() { - setupWarmGasCost(); - given(frame.getStackItem(0)).willReturn(SYSTEM_ADDRESS); - given(addressChecks.isSystemAccount(SYSTEM_ADDRESS)).willReturn(true); - final var expected = new Operation.OperationResult(3L, null); - final var actual = subject.execute(frame, evm); - assertSameResult(expected, actual); - verify(frame).popStackItem(); - verify(frame).pushStackItem(UInt256.ZERO); - } - - @Test - void rejectsMissingUserAddress() { - setupWarmGasCost(); - given(frame.getStackItem(0)).willReturn(NON_SYSTEM_LONG_ZERO_ADDRESS); - final var expected = new Operation.OperationResult(3L, CustomExceptionalHaltReason.MISSING_ADDRESS); - final var actual = subject.execute(frame, evm); - assertSameResult(expected, actual); - } - - @Test - void delegatesToSuperForPresentUserAddress() { - setupWarmGasCost(); - given(frame.getStackItem(0)).willReturn(NON_SYSTEM_LONG_ZERO_ADDRESS); - given(frame.popStackItem()).willReturn(NON_SYSTEM_LONG_ZERO_ADDRESS); - given(frame.warmUpAddress(NON_SYSTEM_LONG_ZERO_ADDRESS)).willReturn(true); - given(addressChecks.isPresent(NON_SYSTEM_LONG_ZERO_ADDRESS, frame)).willReturn(true); - final var expected = new Operation.OperationResult(3L, ExceptionalHaltReason.INSUFFICIENT_GAS); - final var actual = subject.execute(frame, evm); - assertSameResult(expected, actual); - } - - private void setupWarmGasCost() { - given(gasCalculator.getBalanceOperationGasCost()).willReturn(1L); - given(gasCalculator.getWarmStorageReadCost()).willReturn(2L); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCallOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCallOperationTest.java deleted file mode 100644 index 64f88f72a5e4..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCallOperationTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.EIP_1014_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.REQUIRED_GAS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.SYSTEM_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCallOperation; -import com.hedera.node.app.service.contract.impl.test.TestHelpers; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomCallOperationTest { - @Mock - private FeatureFlags featureFlags; - - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private WorldUpdater worldUpdater; - - @Mock - private EVM evm; - - private CustomCallOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomCallOperation(featureFlags, gasCalculator, addressChecks); - } - - @Test - void withImplicitCreationEnabledDoesNoFurtherChecks() { - givenWellKnownFrameWith(1L, TestHelpers.EIP_1014_ADDRESS, 2L); - given(frame.isStatic()).willReturn(true); - given(featureFlags.isImplicitCreationEnabled(frame)).willReturn(true); - - final var expected = new Operation.OperationResult(REQUIRED_GAS, ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void returnsUnderflowResponse() { - given(frame.getStackItem(anyInt())).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void withPresentEip1014ContinuesAsExpected() { - givenWellKnownFrameWith(1L, TestHelpers.EIP_1014_ADDRESS, 2L); - given(addressChecks.isPresent(EIP_1014_ADDRESS, frame)).willReturn(true); - given(frame.isStatic()).willReturn(true); - - final var expected = new Operation.OperationResult(REQUIRED_GAS, ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void withSystemAccountContinuesAsExpected() { - given(frame.getStackItem(1)).willReturn(SYSTEM_ADDRESS); - given(addressChecks.isSystemAccount(SYSTEM_ADDRESS)).willReturn(true); - - final var expected = new Operation.OperationResult(0, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void withLongZeroRejectsMissingAddress() { - givenWellKnownFrameWith(1L, TestHelpers.NON_SYSTEM_LONG_ZERO_ADDRESS, 2L); - - final var expected = new Operation.OperationResult(REQUIRED_GAS, CustomExceptionalHaltReason.MISSING_ADDRESS); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void withNoValueRejectsMissingAddress() { - givenWellKnownFrameWith(0L, TestHelpers.EIP_1014_ADDRESS, 2L); - - final var expected = new Operation.OperationResult(REQUIRED_GAS, CustomExceptionalHaltReason.MISSING_ADDRESS); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - @Test - void withoutImplicitCreationEnabledRejectsMissingAddress() { - givenWellKnownFrameWith(1L, TestHelpers.EIP_1014_ADDRESS, 2L); - - final var expected = new Operation.OperationResult(REQUIRED_GAS, CustomExceptionalHaltReason.MISSING_ADDRESS); - final var actual = subject.execute(frame, evm); - - assertSameResult(expected, actual); - } - - /** - * Return a frame with the given gas, value, and address as the top three stack items. - */ - private void givenWellKnownFrameWith(final long value, final Address to, final long gas) { - given(frame.getWorldUpdater()).willReturn(worldUpdater); - given(frame.getStackItem(0)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(gas))); - given(frame.getStackItem(1)).willReturn(to); - given(frame.getStackItem(2)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(value))); - given(frame.getStackItem(3)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(3))); - given(frame.getStackItem(4)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(4))); - given(frame.getStackItem(5)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(5))); - given(frame.getStackItem(6)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(6))); - given(gasCalculator.callOperationGasCost( - any(), anyLong(), anyLong(), anyLong(), anyLong(), anyLong(), any(), any(), eq(to))) - .willReturn(REQUIRED_GAS); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomChainIdOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomChainIdOperationTest.java deleted file mode 100644 index f620d4f9ec7f..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomChainIdOperationTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.CONFIG_CONTEXT_VARIABLE; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.operations.CustomChainIdOperation; -import com.hedera.node.app.service.contract.impl.test.TestHelpers; -import com.hedera.node.config.data.ContractsConfig; -import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomChainIdOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private EVM evm; - - @Mock - private MessageFrame messageFrame; - - private CustomChainIdOperation subject; - - @BeforeEach - void setUp() { - given(gasCalculator.getBaseTierGasCost()).willReturn(123L); - subject = new CustomChainIdOperation(gasCalculator); - } - - @Test - void usesContractsConfigFromContext() { - final var config = new HederaTestConfigBuilder().getOrCreateConfig(); - given(messageFrame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - given(messageFrame.getRemainingGas()).willReturn(Long.MAX_VALUE); - final var contractsConfig = config.getConfigData(ContractsConfig.class); - final var expectedStackItem = Bytes32.fromHexStringLenient(Integer.toString(contractsConfig.chainId(), 16)); - final var expectedResult = new Operation.OperationResult(123L, null); - final var actualResult = subject.execute(messageFrame, evm); - TestHelpers.assertSameResult(actualResult, expectedResult); - verify(messageFrame).pushStackItem(expectedStackItem); - } - - @Test - void checksForOOG() { - final var expectedResult = new Operation.OperationResult(123L, ExceptionalHaltReason.INSUFFICIENT_GAS); - final var actualResult = subject.execute(messageFrame, evm); - TestHelpers.assertSameResult(actualResult, expectedResult); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreate2OperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreate2OperationTest.java deleted file mode 100644 index de95871015ba..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreate2OperationTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreate2Operation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.MutableBytes; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; - -class CustomCreate2OperationTest extends CreateOperationTestBase { - private static final MutableBytes MUTABLE_INITCODE = MutableBytes.wrap(new byte[] {0x01, 0x02, 0x03}); - private static final Address EIP_1014_ADDRESS = Address.fromHexString("5a86fe448f4811ccf76b71a442aa2e5849168ee8"); - - @Mock - private FeatureFlags featureFlags; - - private CustomCreate2Operation subject; - - @BeforeEach - void setUp() { - subject = new CustomCreate2Operation(gasCalculator, featureFlags); - } - - @Test - void returnsInvalidWhenDisabled() { - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INVALID_OPERATION); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void failsWhenPendingContractIsHollowAccountAndLazyCreationDisabled() { - givenSpawnPrereqs(4); - given(gasCalculator.create2OperationGasCost(frame)).willReturn(GAS_COST); - given(frame.getStackItem(0)).willReturn(Bytes.ofUnsignedLong(VALUE)); - given(frame.readMemory(anyLong(), anyLong())).willReturn(INITCODE); - given(frame.readMutableMemory(anyLong(), anyLong())).willReturn(MUTABLE_INITCODE); - given(featureFlags.isCreate2Enabled(frame)).willReturn(true); - given(worldUpdater.isHollowAccount(EIP_1014_ADDRESS)).willReturn(true); - - final var expected = new Operation.OperationResult(GAS_COST, null); - assertSameResult(expected, subject.execute(frame, evm)); - - verify(worldUpdater, never()).setupCreate2(RECIEVER_ADDRESS, EIP_1014_ADDRESS); - verify(frame).popStackItems(4); - verify(frame).pushStackItem(UInt256.ZERO); - verify(featureFlags).isImplicitCreationEnabled(frame); - } - - @Test - void finalizesHollowAccountWhenPendingContractIsHollowAccountAndLazyCreationEnabled() { - final var frameCaptor = ArgumentCaptor.forClass(MessageFrame.class); - givenBuilderPrereqs(); - givenSpawnPrereqs(4); - given(gasCalculator.create2OperationGasCost(frame)).willReturn(GAS_COST); - given(frame.getStackItem(0)).willReturn(Bytes.ofUnsignedLong(VALUE)); - given(frame.readMemory(anyLong(), anyLong())).willReturn(INITCODE); - given(frame.readMutableMemory(anyLong(), anyLong())).willReturn(MUTABLE_INITCODE); - given(featureFlags.isCreate2Enabled(frame)).willReturn(true); - given(worldUpdater.isHollowAccount(EIP_1014_ADDRESS)).willReturn(true); - given(featureFlags.isImplicitCreationEnabled(frame)).willReturn(true); - - final var expected = new Operation.OperationResult(GAS_COST, null); - assertSameResult(expected, subject.execute(frame, evm)); - - verify(worldUpdater).setupCreate2(RECIEVER_ADDRESS, EIP_1014_ADDRESS); - - verify(stack).addFirst(frameCaptor.capture()); - final var childFrame = frameCaptor.getValue(); - childFrame.setState(MessageFrame.State.COMPLETED_SUCCESS); - childFrame.notifyCompletion(); - verify(frame).pushStackItem(Words.fromAddress(EIP_1014_ADDRESS)); - verify(worldUpdater).finalizeHollowAccount(EIP_1014_ADDRESS); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreateOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreateOperationTest.java deleted file mode 100644 index 5afe12afa329..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomCreateOperationTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.ILLEGAL_STATE_CHANGE; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.operations.CustomCreateOperation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.internal.Words; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -class CustomCreateOperationTest extends CreateOperationTestBase { - - private CustomCreateOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomCreateOperation(gasCalculator); - } - - @Test - void returnsUnderflowWhenStackSizeTooSmall() { - given(frame.stackSize()).willReturn(2); - - final var expected = new Operation.OperationResult(0, INSUFFICIENT_STACK_ITEMS); - - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void haltsOnStaticFrame() { - given(frame.stackSize()).willReturn(3); - given(frame.isStatic()).willReturn(true); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - - final var expected = new Operation.OperationResult(GAS_COST, ILLEGAL_STATE_CHANGE); - - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void haltsOnInsufficientGas() { - given(frame.stackSize()).willReturn(3); - given(frame.getRemainingGas()).willReturn(GAS_COST - 1); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - - final var expected = new Operation.OperationResult(GAS_COST, INSUFFICIENT_GAS); - - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void failsWithInsufficientRecipientBalanceForValue() { - given(frame.stackSize()).willReturn(3); - given(frame.getStackItem(anyInt())).willReturn(Bytes.ofUnsignedLong(1)); - given(frame.getRemainingGas()).willReturn(GAS_COST); - given(frame.getStackItem(0)).willReturn(Bytes.ofUnsignedLong(VALUE)); - given(frame.getRecipientAddress()).willReturn(RECIEVER_ADDRESS); - given(frame.getWorldUpdater()).willReturn(worldUpdater); - given(worldUpdater.getAccount(RECIEVER_ADDRESS)).willReturn(receiver); - given(receiver.getMutable()).willReturn(mutableReceiver); - given(mutableReceiver.getBalance()).willReturn(Wei.ONE); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - - final var expected = new Operation.OperationResult(GAS_COST, null); - - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).pushStackItem(UInt256.ZERO); - } - - @Test - void failsWithExcessStackDepth() { - givenSpawnPrereqs(); - given(frame.getMessageStackDepth()).willReturn(1024); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - - final var expected = new Operation.OperationResult(GAS_COST, null); - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).pushStackItem(UInt256.ZERO); - } - - @Test - void hasExpectedChildCompletionOnSuccess() { - final var frameCaptor = ArgumentCaptor.forClass(MessageFrame.class); - givenSpawnPrereqs(); - givenBuilderPrereqs(); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - given(worldUpdater.setupCreate(RECIEVER_ADDRESS)).willReturn(NEW_CONTRACT_ADDRESS); - given(frame.readMemory(anyLong(), anyLong())).willReturn(INITCODE); - final var expected = new Operation.OperationResult(GAS_COST, null); - assertSameResult(expected, subject.execute(frame, evm)); - - verify(stack).addFirst(frameCaptor.capture()); - final var childFrame = frameCaptor.getValue(); - childFrame.setState(MessageFrame.State.COMPLETED_SUCCESS); - childFrame.notifyCompletion(); - verify(frame).pushStackItem(Words.fromAddress(NEW_CONTRACT_ADDRESS)); - } - - @Test - void hasExpectedChildCompletionOnFailure() { - final var captor = ArgumentCaptor.forClass(MessageFrame.class); - givenSpawnPrereqs(); - givenBuilderPrereqs(); - given(frame.readMemory(anyLong(), anyLong())).willReturn(INITCODE); - given(worldUpdater.setupCreate(RECIEVER_ADDRESS)).willReturn(NEW_CONTRACT_ADDRESS); - given(gasCalculator.createOperationGasCost(frame)).willReturn(GAS_COST); - - final var expected = new Operation.OperationResult(GAS_COST, null); - assertSameResult(expected, subject.execute(frame, evm)); - - verify(stack).addFirst(captor.capture()); - final var childFrame = captor.getValue(); - // when: - childFrame.setState(MessageFrame.State.COMPLETED_FAILED); - childFrame.notifyCompletion(); - verify(frame).pushStackItem(UInt256.ZERO); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomDelegateCallOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomDelegateCallOperationTest.java deleted file mode 100644 index daf4839ed1fb..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomDelegateCallOperationTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.REQUIRED_GAS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doCallRealMethod; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomDelegateCallOperation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomDelegateCallOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private WorldUpdater worldUpdater; - - @Mock - private EVM evm; - - private CustomDelegateCallOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomDelegateCallOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - given(frame.getStackItem(0)).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void rejectsMissingNonSystemAddress() { - doCallRealMethod().when(addressChecks).isNeitherSystemNorPresent(any(), any()); - givenWellKnownFrameWith(1L, Address.fromHexString("0x123"), 2L); - final var expected = new Operation.OperationResult(123L, MISSING_ADDRESS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void permitsSystemAddress() { - doCallRealMethod().when(addressChecks).isNeitherSystemNorPresent(any(), any()); - given(addressChecks.isSystemAccount(Address.fromHexString("0x123"))).willReturn(true); - givenWellKnownFrameWith(1L, Address.fromHexString("0x123"), 2L); - given(frame.stackSize()).willReturn(6); - final var expected = new Operation.OperationResult(123L, INSUFFICIENT_GAS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - private void givenWellKnownFrameWith(final long value, final Address to, final long gas) { - given(frame.getWorldUpdater()).willReturn(worldUpdater); - given(frame.getStackItem(0)).willReturn(to); - given(frame.getStackItem(1)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(gas))); - given(frame.getStackItem(2)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(value))); - given(frame.getStackItem(3)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(3))); - given(frame.getStackItem(4)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(4))); - given(frame.getStackItem(5)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(5))); - given(gasCalculator.callOperationGasCost( - any(), anyLong(), anyLong(), anyLong(), anyLong(), anyLong(), any(), any(), any())) - .willReturn(REQUIRED_GAS); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeCopyOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeCopyOperationTest.java deleted file mode 100644 index 81209e246596..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeCopyOperationTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomExtCodeCopyOperation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomExtCodeCopyOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private EVM evm; - - private CustomExtCodeCopyOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomExtCodeCopyOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - given(frame.getStackItem(0)).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void rejectsMissingUserAddress() { - given(frame.getStackItem(1)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1L))); - given(frame.getStackItem(2)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(2L))); - given(frame.getStackItem(3)).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(3))); - givenWellKnownFrameWith(Address.fromHexString("0x123")); - final var expected = new Operation.OperationResult(123L, MISSING_ADDRESS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void hasSpecialBehaviorForNonUserAccount() { - given(addressChecks.isNonUserAccount(Address.fromHexString("0x123"))).willReturn(true); - given(frame.getStackItem(anyInt())).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - givenWellKnownFrameWith(Address.fromHexString("0x123")); - final var expected = new Operation.OperationResult(123L, null); - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).popStackItems(4); - } - - @Test - void hasNormalBehaviorForUserAccount() { - given(frame.getStackItem(anyInt())).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - given(addressChecks.isPresent(Address.fromHexString("0x123"), frame)).willReturn(true); - givenWellKnownFrameWith(Address.fromHexString("0x123")); - given(frame.popStackItem()).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - final var expected = new Operation.OperationResult(123L, INSUFFICIENT_GAS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - private void givenWellKnownFrameWith(final Address to) { - given(frame.getStackItem(0)).willReturn(to); - given(gasCalculator.extCodeCopyOperationGasCost(eq(frame), anyLong(), anyLong())) - .willReturn(123L); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeHashOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeHashOperationTest.java deleted file mode 100644 index 90beee753177..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeHashOperationTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomExtCodeHashOperation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomExtCodeHashOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private EVM evm; - - private CustomExtCodeHashOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomExtCodeHashOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - given(frame.getStackItem(0)).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void rejectsMissingNonSystemAddress() { - givenWellKnownFrameWith(Address.fromHexString("0x123")); - final var expected = new Operation.OperationResult(123L, MISSING_ADDRESS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void hasSpecialBehaviorForNonUserAccount() { - given(addressChecks.isNonUserAccount(Address.fromHexString("0x123"))).willReturn(true); - given(frame.getStackItem(anyInt())).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - givenWellKnownFrameWith(Address.fromHexString("0x123")); - final var expected = new Operation.OperationResult(123L, null); - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).popStackItem(); - verify(frame).pushStackItem(UInt256.ZERO); - } - - @Test - void delegatesForPresentAddress() { - givenWellKnownFrameWith(Address.fromHexString("0x123")); - given(addressChecks.isPresent(Address.fromHexString("0x123"), frame)).willReturn(true); - given(frame.popStackItem()).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - final var expected = new Operation.OperationResult(123L, INSUFFICIENT_GAS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - private void givenWellKnownFrameWith(final Address to) { - given(frame.getStackItem(0)).willReturn(to); - given(gasCalculator.extCodeHashOperationGasCost()).willReturn(123L); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeSizeOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeSizeOperationTest.java deleted file mode 100644 index ca5a9e092e13..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomExtCodeSizeOperationTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomExtCodeSizeOperation; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomExtCodeSizeOperationTest { - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private EVM evm; - - private CustomExtCodeSizeOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomExtCodeSizeOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - given(frame.getStackItem(0)).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void hasSpecialBehaviorForNonUserAccount() { - given(addressChecks.isNonUserAccount(Address.fromHexString("0x123"))).willReturn(true); - given(frame.getStackItem(anyInt())).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - givenWellKnownFrameWith(Address.fromHexString("0x123")); - final var expected = new Operation.OperationResult(123L, null); - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).popStackItem(); - verify(frame).pushStackItem(UInt256.ZERO); - } - - @Test - void delegatesForPresentAddress() { - givenWellKnownFrameWith(Address.fromHexString("0x123")); - given(addressChecks.isPresent(Address.fromHexString("0x123"), frame)).willReturn(true); - given(frame.popStackItem()).willReturn(Bytes32.leftPad(Bytes.ofUnsignedLong(1))); - final var expected = new Operation.OperationResult(123L, INSUFFICIENT_GAS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - private void givenWellKnownFrameWith(final Address to) { - given(frame.getStackItem(0)).willReturn(to); - given(gasCalculator.getExtCodeSizeOperationGasCost()).willReturn(123L); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomSelfDestructOperationTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomSelfDestructOperationTest.java deleted file mode 100644 index bf9c48d5f4df..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/operations/CustomSelfDestructOperationTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.operations; - -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_RECEIVER_SIGNATURE; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.SELFDESTRUCT_TO_SELF; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.assertSameResult; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.INSUFFICIENT_GAS; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import com.hedera.node.app.service.contract.impl.exec.operations.CustomSelfDestructOperation; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import java.util.Optional; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.FixedStack; -import org.hyperledger.besu.evm.operation.Operation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomSelfDestructOperationTest { - private static final long COLD_ACCESS_COST = 1L; - private static final Wei INHERITANCE = Wei.of(666L); - private static final Address TBD = Address.fromHexString("0xa234567890abcdefa234567890abcdefa2345678"); - private static final Address BENEFICIARY = Address.fromHexString("0x1234567890abcdef1234567890abcdef12345678"); - - @Mock - private GasCalculator gasCalculator; - - @Mock - private AddressChecks addressChecks; - - @Mock - private MessageFrame frame; - - @Mock - private EVM evm; - - @Mock - private ProxyWorldUpdater proxyWorldUpdater; - - @Mock - private Account account; - - private CustomSelfDestructOperation subject; - - @BeforeEach - void setUp() { - subject = new CustomSelfDestructOperation(gasCalculator, addressChecks); - } - - @Test - void catchesUnderflowWhenStackIsEmpty() { - given(frame.popStackItem()).willThrow(FixedStack.UnderflowException.class); - final var expected = new Operation.OperationResult(0L, ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void rejectsSystemBeneficiaryAsMissing() { - given(frame.popStackItem()).willReturn(BENEFICIARY); - given(addressChecks.isSystemAccount(BENEFICIARY)).willReturn(true); - given(gasCalculator.selfDestructOperationGasCost(null, Wei.ZERO)).willReturn(123L); - final var expected = new Operation.OperationResult(123L, CustomExceptionalHaltReason.MISSING_ADDRESS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void respectsHederaCustomHaltReason() { - given(frame.popStackItem()).willReturn(BENEFICIARY); - given(frame.getRecipientAddress()).willReturn(TBD); - given(addressChecks.isPresent(BENEFICIARY, frame)).willReturn(true); - given(frame.getWorldUpdater()).willReturn(proxyWorldUpdater); - given(gasCalculator.selfDestructOperationGasCost(null, Wei.ZERO)).willReturn(123L); - given(proxyWorldUpdater.tryTrackingDeletion(TBD, BENEFICIARY)).willReturn(Optional.of(SELFDESTRUCT_TO_SELF)); - final var expected = new Operation.OperationResult(123L, SELFDESTRUCT_TO_SELF); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void rejectsSelfDestructInStaticChanges() { - givenRunnableSelfDestruct(); - given(frame.isStatic()).willReturn(true); - given(gasCalculator.getColdAccountAccessCost()).willReturn(COLD_ACCESS_COST); - given(gasCalculator.selfDestructOperationGasCost(null, INHERITANCE)).willReturn(123L); - final var expected = - new Operation.OperationResult(123L + COLD_ACCESS_COST, ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void haltsSelfDestructWithInsufficientGas() { - givenRunnableSelfDestruct(); - given(frame.warmUpAddress(BENEFICIARY)).willReturn(true); - given(gasCalculator.selfDestructOperationGasCost(null, INHERITANCE)).willReturn(123L); - final var expected = new Operation.OperationResult(123L, INSUFFICIENT_GAS); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void haltsSelfDestructOnFailedInheritanceTransfer() { - givenRunnableSelfDestruct(); - givenWarmBeneficiaryWithSufficientGas(); - given(proxyWorldUpdater.tryTransferFromContract(TBD, BENEFICIARY, INHERITANCE.toLong(), true)) - .willReturn(Optional.of(INVALID_RECEIVER_SIGNATURE)); - final var expected = new Operation.OperationResult(123L, INVALID_RECEIVER_SIGNATURE); - assertSameResult(expected, subject.execute(frame, evm)); - } - - @Test - void finalizesFrameAsExpected() { - givenRunnableSelfDestruct(); - givenWarmBeneficiaryWithSufficientGas(); - given(frame.getContractAddress()).willReturn(TBD); - given(proxyWorldUpdater.tryTransferFromContract(TBD, BENEFICIARY, INHERITANCE.toLong(), false)) - .willReturn(Optional.empty()); - final var expected = new Operation.OperationResult(123L, null); - assertSameResult(expected, subject.execute(frame, evm)); - verify(frame).addSelfDestruct(TBD); - verify(frame).addRefund(BENEFICIARY, INHERITANCE); - verify(frame).setState(MessageFrame.State.CODE_SUCCESS); - } - - private void givenWarmBeneficiaryWithSufficientGas() { - given(frame.warmUpAddress(BENEFICIARY)).willReturn(true); - given(frame.getRemainingGas()).willReturn(666L); - given(gasCalculator.selfDestructOperationGasCost(null, INHERITANCE)).willReturn(123L); - } - - private void givenRunnableSelfDestruct() { - given(frame.popStackItem()).willReturn(BENEFICIARY); - given(frame.getRecipientAddress()).willReturn(TBD); - given(addressChecks.isPresent(BENEFICIARY, frame)).willReturn(true); - given(frame.getWorldUpdater()).willReturn(proxyWorldUpdater); - given(proxyWorldUpdater.tryTrackingDeletion(TBD, BENEFICIARY)).willReturn(Optional.empty()); - given(proxyWorldUpdater.get(TBD)).willReturn(account); - given(account.getBalance()).willReturn(INHERITANCE); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/processors/CustomMessageCallProcessorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/processors/CustomMessageCallProcessorTest.java deleted file mode 100644 index f1bdbae80933..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/processors/CustomMessageCallProcessorTest.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.processors; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.isSameResult; -import static org.hyperledger.besu.datatypes.Address.ALTBN128_ADD; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.AddressChecks; -import com.hedera.node.app.service.contract.impl.exec.FeatureFlags; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; -import com.hedera.node.app.service.contract.impl.exec.processors.CustomMessageCallProcessor; -import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; -import com.hedera.node.app.service.contract.impl.test.TestHelpers; -import com.swirlds.config.api.Configuration; -import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.operation.Operation; -import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class CustomMessageCallProcessorTest { - private static final long GAS_REQUIREMENT = 2L; - private static final Bytes INPUT_DATA = Bytes.fromHexString("0x1234"); - private static final Bytes OUTPUT_DATA = Bytes.fromHexString("0x5678"); - private static final Address NON_EVM_PRECOMPILE_SYSTEM_ADDRESS = Address.fromHexString("0x222"); - private static final Address CODE_ADDRESS = Address.fromHexString("0x111222333"); - private static final Address SENDER_ADDRESS = Address.fromHexString("0x222333444"); - private static final Address RECEIVER_ADDRESS = Address.fromHexString("0x33344455"); - - @Mock - private EVM evm; - - @Mock - private MessageFrame frame; - - @Mock - private FeatureFlags featureFlags; - - @Mock - private AddressChecks addressChecks; - - @Mock - private PrecompiledContract htsPrecompile; - - @Mock - private PrecompiledContract nativePrecompile; - - @Mock - private OperationTracer operationTracer; - - @Mock - private PrecompileContractRegistry registry; - - @Mock - private Configuration config; - - @Mock - private ProxyWorldUpdater proxyWorldUpdater; - - private CustomMessageCallProcessor subject; - - @BeforeEach - void setUp() { - subject = new CustomMessageCallProcessor( - evm, featureFlags, registry, addressChecks, Map.of(TestHelpers.HTS_PRECOMPILE_ADDRESS, htsPrecompile)); - } - - @Test - void delegatesLazyCreationCheck() { - given(featureFlags.isImplicitCreationEnabled(config)).willReturn(true); - assertTrue(subject.isImplicitCreationEnabled(config)); - } - - @Test - void hederaPrecompilesNotYetSupported() { - givenCallWithCode(TestHelpers.HTS_PRECOMPILE_ADDRESS); - assertThrows(UnsupportedOperationException.class, () -> subject.start(frame, operationTracer)); - } - - @Test - void callsToNonStandardSystemContractsAreNotSupported() { - final var isHalted = new AtomicBoolean(); - givenHaltableFrame(isHalted); - givenCallWithCode(NON_EVM_PRECOMPILE_SYSTEM_ADDRESS); - given(addressChecks.isSystemAccount(NON_EVM_PRECOMPILE_SYSTEM_ADDRESS)).willReturn(true); - - subject.start(frame, operationTracer); - - verifyHalt(ExceptionalHaltReason.PRECOMPILE_ERROR); - } - - @Test - void valueCannotBeTransferredToSystemContracts() { - final var isHalted = new AtomicBoolean(); - givenHaltableFrame(isHalted); - givenCallWithCode(ALTBN128_ADD); - given(addressChecks.isSystemAccount(ALTBN128_ADD)).willReturn(true); - given(registry.get(ALTBN128_ADD)).willReturn(nativePrecompile); - given(frame.getValue()).willReturn(Wei.ONE); - - subject.start(frame, operationTracer); - - verifyHalt(CustomExceptionalHaltReason.INVALID_VALUE_TRANSFER); - } - - @Test - void haltsIfValueTransferFails() { - final var isHalted = new AtomicBoolean(); - givenWellKnownUserSpaceCall(); - givenHaltableFrame(isHalted); - given(frame.getValue()).willReturn(Wei.ONE); - given(frame.getWorldUpdater()).willReturn(proxyWorldUpdater); - given(addressChecks.isPresent(RECEIVER_ADDRESS, frame)).willReturn(true); - given(proxyWorldUpdater.tryTransferFromContract(SENDER_ADDRESS, RECEIVER_ADDRESS, Wei.ONE.toLong(), true)) - .willReturn(Optional.of(ExceptionalHaltReason.ILLEGAL_STATE_CHANGE)); - - subject.start(frame, operationTracer); - - verifyHalt(ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); - } - - @Test - void haltsIfPrecompileGasRequirementExceedsRemaining() { - final var isHalted = new AtomicBoolean(); - givenHaltableFrame(isHalted); - givenEvmPrecompileCall(); - given(nativePrecompile.gasRequirement(INPUT_DATA)).willReturn(GAS_REQUIREMENT); - given(frame.getRemainingGas()).willReturn(1L); - - subject.start(frame, operationTracer); - - verifyHalt(ExceptionalHaltReason.INSUFFICIENT_GAS, false); - } - - @Test - void updatesFrameBySuccessfulPrecompileResultWithGasRefund() { - givenEvmPrecompileCall(); - final var result = new PrecompiledContract.PrecompileContractResult( - OUTPUT_DATA, true, MessageFrame.State.CODE_SUCCESS, Optional.empty()); - given(nativePrecompile.computePrecompile(INPUT_DATA, frame)).willReturn(result); - given(nativePrecompile.gasRequirement(INPUT_DATA)).willReturn(GAS_REQUIREMENT); - given(frame.getRemainingGas()).willReturn(3L); - given(frame.getState()).willReturn(MessageFrame.State.COMPLETED_SUCCESS); - - subject.start(frame, operationTracer); - - verify(operationTracer).tracePrecompileCall(frame, GAS_REQUIREMENT, OUTPUT_DATA); - verify(frame).decrementRemainingGas(GAS_REQUIREMENT); - verify(frame).incrementRemainingGas(GAS_REQUIREMENT); - verify(frame).setOutputData(OUTPUT_DATA); - verify(frame).setState(MessageFrame.State.CODE_SUCCESS); - verify(frame).setExceptionalHaltReason(Optional.empty()); - } - - @Test - void revertsFrameFromPrecompileResult() { - givenEvmPrecompileCall(); - final var result = new PrecompiledContract.PrecompileContractResult( - OUTPUT_DATA, false, MessageFrame.State.REVERT, Optional.empty()); - given(nativePrecompile.computePrecompile(INPUT_DATA, frame)).willReturn(result); - given(nativePrecompile.gasRequirement(INPUT_DATA)).willReturn(GAS_REQUIREMENT); - given(frame.getRemainingGas()).willReturn(3L); - given(frame.getState()).willReturn(MessageFrame.State.REVERT); - - subject.start(frame, operationTracer); - - verify(operationTracer).tracePrecompileCall(frame, GAS_REQUIREMENT, OUTPUT_DATA); - verify(frame).decrementRemainingGas(GAS_REQUIREMENT); - verify(frame).setRevertReason(OUTPUT_DATA); - verify(frame, never()).setOutputData(OUTPUT_DATA); - verify(frame).setState(MessageFrame.State.REVERT); - verify(frame).setExceptionalHaltReason(Optional.empty()); - } - - @Test - void triesLazyCreationBeforeValueTransferIfRecipientMissing() { - givenWellKnownUserSpaceCall(); - given(frame.getValue()).willReturn(Wei.ONE); - given(frame.getWorldUpdater()).willReturn(proxyWorldUpdater); - given(proxyWorldUpdater.tryLazyCreation(RECEIVER_ADDRESS, frame)).willReturn(Optional.empty()); - given(proxyWorldUpdater.tryTransferFromContract(SENDER_ADDRESS, RECEIVER_ADDRESS, Wei.ONE.toLong(), true)) - .willReturn(Optional.empty()); - - subject.start(frame, operationTracer); - - verify(frame).setState(MessageFrame.State.CODE_EXECUTING); - } - - private void givenHaltableFrame(@NonNull final AtomicBoolean isHalted) { - doAnswer(invocation -> { - isHalted.set(true); - return null; - }) - .when(frame) - .setExceptionalHaltReason(any()); - doAnswer(invocation -> isHalted.get() ? MessageFrame.State.EXCEPTIONAL_HALT : MessageFrame.State.NOT_STARTED) - .when(frame) - .getState(); - } - - private void givenCallWithCode(@NonNull final Address contract) { - given(frame.getContractAddress()).willReturn(contract); - } - - private void givenWellKnownUserSpaceCall() { - given(frame.getContractAddress()).willReturn(CODE_ADDRESS); - given(frame.getRecipientAddress()).willReturn(RECEIVER_ADDRESS); - given(frame.getSenderAddress()).willReturn(SENDER_ADDRESS); - } - - private void givenEvmPrecompileCall() { - given(addressChecks.isSystemAccount(ALTBN128_ADD)).willReturn(true); - given(registry.get(ALTBN128_ADD)).willReturn(nativePrecompile); - given(frame.getContractAddress()).willReturn(ALTBN128_ADD); - given(frame.getInputData()).willReturn(INPUT_DATA); - given(frame.getValue()).willReturn(Wei.ZERO); - } - - private void verifyHalt(@NonNull final ExceptionalHaltReason reason) { - verifyHalt(reason, true); - } - - private void verifyHalt(@NonNull final ExceptionalHaltReason reason, final boolean alsoVerifyTrace) { - verify(frame).setExceptionalHaltReason(Optional.of(reason)); - verify(frame).setState(MessageFrame.State.EXCEPTIONAL_HALT); - verify(frame, never()).setState(MessageFrame.State.CODE_EXECUTING); - if (alsoVerifyTrace) { - verify(operationTracer) - .tracePostExecution( - eq(frame), - argThat(result -> isSameResult(new Operation.OperationResult(0, reason), result))); - } - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030AddressChecksTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030AddressChecksTest.java deleted file mode 100644 index 42b3bc85f0f1..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030AddressChecksTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.v030; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.EIP_1014_ADDRESS; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.HTS_PRECOMPILE_ADDRESS; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.BDDMockito.given; - -import com.hedera.node.app.service.contract.impl.exec.v030.Version030AddressChecks; -import java.util.Map; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class Version030AddressChecksTest { - @Mock - private PrecompiledContract mockHtsPrecompile; - - @Mock - private PrecompiledContract mockPrngPrecompile; - - @Mock - private PrecompiledContract mockRatesPrecompile; - - @Mock - private MessageFrame frame; - - @Mock - private WorldUpdater worldUpdater; - - @Mock - private Account account; - - private Version030AddressChecks subject; - - @BeforeEach - void setUp() { - subject = new Version030AddressChecks(Map.of( - HTS_PRECOMPILE_ADDRESS, - mockHtsPrecompile, - Address.fromHexString("0x168"), - mockRatesPrecompile, - Address.fromHexString("0x169"), - mockPrngPrecompile)); - } - - @Test - void classifiesPrecompiles() { - assertTrue(subject.isHederaPrecompile(HTS_PRECOMPILE_ADDRESS)); - assertTrue(subject.isHederaPrecompile(Address.fromHexString("0x168"))); - assertTrue(subject.isHederaPrecompile(Address.fromHexString("0x169"))); - assertFalse(subject.isHederaPrecompile(Address.fromHexString("0x16a"))); - } - - @Test - void precompilesAlwaysPresent() { - given(frame.getWorldUpdater()).willReturn(worldUpdater); - assertTrue(subject.isPresent(HTS_PRECOMPILE_ADDRESS, frame)); - assertTrue(subject.isPresent(Address.fromHexString("0x168"), frame)); - assertTrue(subject.isPresent(Address.fromHexString("0x169"), frame)); - assertFalse(subject.isPresent(Address.fromHexString("0x16a"), frame)); - } - - @Test - void nonNullAccountIsPresent() { - given(frame.getWorldUpdater()).willReturn(worldUpdater); - given(worldUpdater.get(EIP_1014_ADDRESS)).willReturn(account); - assertTrue(subject.isPresent(EIP_1014_ADDRESS, frame)); - } - - @Test - void nothingIsSystemAccount() { - assertFalse(subject.isSystemAccount(HTS_PRECOMPILE_ADDRESS)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030FeatureFlagsTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030FeatureFlagsTest.java deleted file mode 100644 index a1b036b7cce3..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v030/Version030FeatureFlagsTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.v030; - -import static com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.CONFIG_CONTEXT_VARIABLE; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.BDDMockito.given; - -import com.hedera.node.app.service.contract.impl.exec.v030.Version030FeatureFlags; -import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class Version030FeatureFlagsTest { - @Mock - private MessageFrame frame; - - private Version030FeatureFlags subject = new Version030FeatureFlags(); - - @Test - void everythingIsDisabled() { - final var config = new HederaTestConfigBuilder().getOrCreateConfig(); - given(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - assertFalse(subject.isImplicitCreationEnabled(frame)); - } - - @Test - void create2FeatureFlagWorks() { - final var config = new HederaTestConfigBuilder() - .withValue("contracts.allowCreate2", false) - .getOrCreateConfig(); - given(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - assertFalse(subject.isCreate2Enabled(frame)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v034/Version034FeatureFlagsTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v034/Version034FeatureFlagsTest.java deleted file mode 100644 index 6640c16537f3..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v034/Version034FeatureFlagsTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.v034; - -import static com.hedera.node.app.service.contract.impl.exec.TransactionProcessor.CONFIG_CONTEXT_VARIABLE; -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.v034.Version034FeatureFlags; -import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class Version034FeatureFlagsTest { - @Mock - private MessageFrame frame; - - private Version034FeatureFlags subject = new Version034FeatureFlags(); - - @Test - void implicitCreationEnabledIfLazyAndAutoCreationBothEnabled() { - final var config = new HederaTestConfigBuilder().getOrCreateConfig(); - given(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - assertTrue(subject.isImplicitCreationEnabled(frame)); - } - - @Test - void implicitCreationNotEnabledIfLazyCreationNotEnabled() { - final var config = new HederaTestConfigBuilder() - .withValue("lazyCreation.enabled", false) - .getOrCreateConfig(); - given(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - assertFalse(subject.isImplicitCreationEnabled(frame)); - } - - @Test - void implicitCreationNotEnabledIfAutoCreationNotEnabled() { - final var config = new HederaTestConfigBuilder() - .withValue("autoCreation.enabled", false) - .getOrCreateConfig(); - given(frame.getContextVariable(CONFIG_CONTEXT_VARIABLE)).willReturn(config); - assertFalse(subject.isImplicitCreationEnabled(frame)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v038/Version038AddressChecksTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v038/Version038AddressChecksTest.java deleted file mode 100644 index ef6744c7151e..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/exec/v038/Version038AddressChecksTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.exec.v038; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.hedera.node.app.service.contract.impl.exec.v038.Version038AddressChecks; -import com.hedera.node.app.service.contract.impl.test.TestHelpers; -import java.util.Map; -import org.hyperledger.besu.datatypes.Address; -import org.junit.jupiter.api.Test; - -class Version038AddressChecksTest { - private Version038AddressChecks subject = new Version038AddressChecks(Map.of()); - - @Test - void onlyBelow750IsSystem() { - assertTrue(subject.isSystemAccount(Address.fromHexString(Integer.toHexString(749)))); - assertTrue(subject.isSystemAccount(Address.fromHexString(Integer.toHexString(750)))); - assertFalse(subject.isSystemAccount(Address.fromHexString(Integer.toHexString(751)))); - assertFalse(subject.isSystemAccount(TestHelpers.EIP_1014_ADDRESS)); - } - - @Test - void onlyAbove1000IsUserAccount() { - assertTrue(subject.isNonUserAccount(Address.fromHexString(Integer.toHexString(1000)))); - assertFalse(subject.isNonUserAccount(Address.fromHexString(Integer.toHexString(1001)))); - assertFalse(subject.isSystemAccount(TestHelpers.EIP_1014_ADDRESS)); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionProcessorTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionProcessorTest.java deleted file mode 100644 index fc5629fbef9c..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionProcessorTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.hevm; - -import static com.hedera.node.app.service.contract.impl.hevm.HederaEvmVersion.*; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.wellKnownContextWith; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.wellKnownHapiCall; -import static org.mockito.Mockito.verify; - -import com.hedera.node.app.service.contract.impl.exec.TransactionProcessor; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmBlocks; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionProcessor; -import com.hedera.node.app.service.contract.impl.hevm.HederaWorldUpdater; -import com.swirlds.config.api.Configuration; -import java.util.Map; -import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class HederaEvmTransactionProcessorTest { - @Mock - private HederaEvmBlocks blocks; - - @Mock - private HederaWorldUpdater worldUpdater; - - @Mock - private OperationTracer tracer; - - @Mock - private Configuration config; - - @Mock - private TransactionProcessor v30processor; - - @Mock - private TransactionProcessor v34processor; - - @Mock - private TransactionProcessor v38processor; - - private HederaEvmTransactionProcessor subject; - - @BeforeEach - void setUp() { - subject = new HederaEvmTransactionProcessor(Map.of( - VERSION_030, v30processor, - VERSION_034, v34processor, - VERSION_038, v38processor)); - } - - @Test - void calls030AsExpected() { - final var transaction = wellKnownHapiCall(); - final var context = wellKnownContextWith(blocks, false); - - subject.process(transaction, worldUpdater, context, VERSION_030, tracer, config); - - verify(v30processor).processTransaction(transaction, worldUpdater, context, tracer, config); - } - - @Test - void calls034AsExpected() { - final var transaction = wellKnownHapiCall(); - final var context = wellKnownContextWith(blocks, false); - - subject.process(transaction, worldUpdater, context, VERSION_034, tracer, config); - - verify(v34processor).processTransaction(transaction, worldUpdater, context, tracer, config); - } - - @Test - void calls038AsExpected() { - final var transaction = wellKnownHapiCall(); - final var context = wellKnownContextWith(blocks, false); - - subject.process(transaction, worldUpdater, context, VERSION_038, tracer, config); - - verify(v38processor).processTransaction(transaction, worldUpdater, context, tracer, config); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionResultTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionResultTest.java deleted file mode 100644 index dfd3a0e05b0d..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionResultTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.hevm; - -import static org.junit.jupiter.api.Assertions.*; - -import com.hedera.hapi.node.base.ResponseCodeEnum; -import com.hedera.node.app.service.contract.impl.hevm.HederaEvmTransactionResult; -import org.junit.jupiter.api.Test; - -class HederaEvmTransactionResultTest { - @Test - void abortsWithTranslatedStatus() { - var subject = HederaEvmTransactionResult.abortFor(ResponseCodeEnum.INVALID_SIGNATURE); - - assertEquals(ResponseCodeEnum.INVALID_SIGNATURE, subject.abortReason()); - } - - @Test - void computesUpfrontCostNoOverflow() {} -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionTest.java deleted file mode 100644 index 184169ea5d24..000000000000 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/hevm/HederaEvmTransactionTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.node.app.service.contract.impl.test.hevm; - -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.GAS_LIMIT; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.VALUE; -import static org.junit.jupiter.api.Assertions.*; - -import com.hedera.node.app.service.contract.impl.test.TestHelpers; -import org.junit.jupiter.api.Test; - -class HederaEvmTransactionTest { - @Test - void computesUpfrontCostWithoutOverflowConcern() { - final var subject = TestHelpers.wellKnownHapiCall(); - assertEquals(VALUE + 123L * GAS_LIMIT, subject.upfrontCostGiven(123L)); - } - - @Test - void computesUpfrontCostWithOverflow() { - final var subject = TestHelpers.wellKnownHapiCall(); - assertEquals(Long.MAX_VALUE, subject.upfrontCostGiven(Long.MAX_VALUE / (GAS_LIMIT - 1))); - } -} diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/BaseProxyWorldUpdaterTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/BaseProxyWorldUpdaterTest.java index 081b37127777..b8190a1abd12 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/BaseProxyWorldUpdaterTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/BaseProxyWorldUpdaterTest.java @@ -20,11 +20,11 @@ import com.hedera.hapi.node.state.contract.SlotKey; import com.hedera.hapi.node.state.contract.SlotValue; +import com.hedera.node.app.service.contract.impl.ContractServiceImpl; import com.hedera.node.app.service.contract.impl.infra.LegibleStorageManager; import com.hedera.node.app.service.contract.impl.infra.RentCalculator; import com.hedera.node.app.service.contract.impl.infra.StorageSizeValidator; import com.hedera.node.app.service.contract.impl.state.BaseProxyWorldUpdater; -import com.hedera.node.app.service.contract.impl.state.ContractSchema; import com.hedera.node.app.service.contract.impl.state.EvmFrameState; import com.hedera.node.app.service.contract.impl.state.EvmFrameStateFactory; import com.hedera.node.app.service.contract.impl.state.RentFactors; @@ -122,7 +122,7 @@ void performsAdditionalCommitActionsInOrder() { given(fees.costInTinybars(rentInTinycents)).willReturn(rentInTinybars); given(scope.writableContractState()).willReturn(writableStates); - given(writableStates.get(ContractSchema.STORAGE_KEY)) + given(writableStates.get(ContractServiceImpl.STORAGE_KEY)) .willReturn(storage); subject.commit(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/DispatchingEvmFrameStateTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/DispatchingEvmFrameStateTest.java index b2ae94936a21..64dc2a0187ec 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/DispatchingEvmFrameStateTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/DispatchingEvmFrameStateTest.java @@ -16,49 +16,28 @@ package com.hedera.node.app.service.contract.impl.test.state; -import static com.hedera.hapi.node.base.ResponseCodeEnum.INSUFFICIENT_ACCOUNT_BALANCE; -import static com.hedera.hapi.node.base.ResponseCodeEnum.INVALID_SIGNATURE; -import static com.hedera.hapi.node.base.ResponseCodeEnum.OK; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_RECEIVER_SIGNATURE; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_VALUE_TRANSFER; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.MISSING_ADDRESS; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.SELFDESTRUCT_TO_SELF; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.TOKEN_HOLDER_SELFDESTRUCT; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.TOKEN_TREASURY_SELFDESTRUCT; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToTuweniBytes; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToTuweniUInt256; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.tuweniToPbjBytes; -import static org.hyperledger.besu.evm.frame.ExceptionalHaltReason.ILLEGAL_STATE_CHANGE; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import com.hedera.hapi.node.base.Key; -import com.hedera.hapi.node.base.KeyList; -import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.hapi.node.state.common.EntityNumber; import com.hedera.hapi.node.state.contract.Bytecode; import com.hedera.hapi.node.state.contract.SlotKey; import com.hedera.hapi.node.state.contract.SlotValue; import com.hedera.hapi.node.state.token.Account; import com.hedera.hapi.node.state.token.Token; -import com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason; import com.hedera.node.app.service.contract.impl.state.DispatchingEvmFrameState; import com.hedera.node.app.service.contract.impl.state.ProxyEvmAccount; import com.hedera.node.app.service.contract.impl.state.TokenEvmAccount; -import com.hedera.node.app.spi.meta.bni.ActiveContractVerificationStrategy; import com.hedera.node.app.spi.meta.bni.Dispatch; -import com.hedera.node.app.spi.meta.bni.VerificationStrategy; import com.hedera.node.app.spi.state.WritableKVState; import com.hedera.pbj.runtime.io.buffer.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -70,7 +49,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -79,13 +57,10 @@ class DispatchingEvmFrameStateTest { private static final int REDIRECT_CODE_FIXED_PREFIX_LEN = "6080604052348015600f57600080fd5b506000610167905077618dc65e".length(); private static final long ACCOUNT_NUM = 0x9abcdefabcdefbbbL; - private static final long BENEFICIARY_NUM = 0xdefdefL; private static final long TOKEN_NUM = 0xffffffffffffL; private static final Bytes SOME_OTHER_ALIAS = Bytes.wrap(""); private static final Address EVM_ADDRESS = Address.fromHexString("abcabcabcabcabcabeeeeeee9abcdefabcdefbbb"); private static final Address LONG_ZERO_ADDRESS = Address.fromHexString("0000000000000000000000009abcdefabcdefbbb"); - private static final Address BENEFICIARY_ADDRESS = - Address.fromHexString("0000000000000000000000000000000000defdef"); private static final Address TOKEN_ADDRESS = Address.fromHexString("0000000000000000000000000000ffffffffffff"); private static final Bytes SOME_PRETEND_CODE = Bytes.wrap(""); private static final Bytecode SOME_PRETEND_BYTECODE = @@ -128,13 +103,6 @@ void dispatchesToSetNonce() { verify(dispatch).setNonce(ACCOUNT_NUM, 1234); } - @Test - void dispatchesToFinalizeHollowAccount() { - subject.finalizeHollowAccount(EVM_ADDRESS); - - verify(dispatch).finalizeHollowAccountAsContract(tuweniToPbjBytes(EVM_ADDRESS)); - } - @Test void dispatchesToSetCode() { final var expectedCode = Bytecode.newBuilder().code(SOME_PRETEND_CODE).build(); @@ -269,12 +237,6 @@ void returnsLongZeroAddressWithoutAnAlias() { assertEquals(LONG_ZERO_ADDRESS, subject.getAddress(ACCOUNT_NUM)); } - @Test - void returnsNullWithDeletedAccount() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).deleted(true)); - assertNull(subject.getAddress(ACCOUNT_NUM)); - } - @Test void returnsLongZeroAddressWithNonAddressAlias() { givenWellKnownAccount(accountWith(ACCOUNT_NUM, SOME_OTHER_ALIAS)); @@ -298,24 +260,6 @@ void returnsNonceIfPresent() { assertEquals(1234, subject.getNonce(ACCOUNT_NUM)); } - @Test - void returnsNumTreasuryTitlesIfPresent() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).numberTreasuryTitles(1234)); - assertEquals(1234, subject.getNumTreasuryTitles(ACCOUNT_NUM)); - } - - @Test - void returnsNumNonZeroBalancesIfPresent() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).numberPositiveBalances(1234)); - assertEquals(1234, subject.getNumPositiveTokenBalances(ACCOUNT_NUM)); - } - - @Test - void returnsWhetherAnAccountIsContract() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - assertTrue(subject.isContract(ACCOUNT_NUM)); - } - @Test void returnsBalanceIfPresent() { final var value = Wei.of(1234); @@ -340,235 +284,6 @@ void returnsNullForExpired() { assertNull(subject.getAccount(LONG_ZERO_ADDRESS)); } - @Test - void missingAccountsCannotBeBeneficiaries() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).expiredAndPendingRemoval(true)); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(EVM_ADDRESS, LONG_ZERO_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(MISSING_ADDRESS, reasonToHaltDeletion.get()); - } - - @Test - void missingAccountsCannotPayFees() { - assertThrows(IllegalArgumentException.class, () -> subject.collectFee(EVM_ADDRESS, 123L)); - } - - @Test - void delegatesFeeCollection() { - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - - subject.collectFee(EVM_ADDRESS, 123L); - - verify(dispatch).collectFee(ACCOUNT_NUM, 123L); - } - - @Test - void missingAccountsCannotGetRefunds() { - assertThrows(IllegalArgumentException.class, () -> subject.refundFee(EVM_ADDRESS, 123L)); - } - - @Test - void delegatesFeeRefunding() { - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - - subject.refundFee(EVM_ADDRESS, 123L); - - verify(dispatch).refundFee(ACCOUNT_NUM, 123L); - } - - @Test - void missingAccountsCannotTransferFunds() { - final var reasonToHaltDeletion = subject.tryTransferFromContract(EVM_ADDRESS, LONG_ZERO_ADDRESS, 123L, true); - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(MISSING_ADDRESS, reasonToHaltDeletion.get()); - } - - @Test - void nonContractAccountsShouldNeverBeTransferringFunds() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM)); - assertThrows( - IllegalArgumentException.class, - () -> subject.tryTransferFromContract(LONG_ZERO_ADDRESS, EVM_ADDRESS, 123L, true)); - } - - @Test - void cannotTransferToMissingAccount() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - final var reasonToHaltDeletion = subject.tryTransferFromContract(LONG_ZERO_ADDRESS, EVM_ADDRESS, 123L, true); - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(MISSING_ADDRESS, reasonToHaltDeletion.get()); - } - - @Test - void cannotTransferToTokenAccount() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - givenWellKnownToken(); - final var reasonToHaltDeletion = subject.tryTransferFromContract(LONG_ZERO_ADDRESS, TOKEN_ADDRESS, 123L, true); - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(ILLEGAL_STATE_CHANGE, reasonToHaltDeletion.get()); - } - - @Test - void cannotLazyCreateOverExpiredAccount() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).expiredAndPendingRemoval(true)); - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - - final var reasonLazyCreationFailed = subject.tryLazyCreation(EVM_ADDRESS); - - assertTrue(reasonLazyCreationFailed.isPresent()); - assertEquals(INVALID_VALUE_TRANSFER, reasonLazyCreationFailed.get()); - } - - @Test - void translatesMaxChildRecordsExceeded() { - given(dispatch.createHollowAccount(tuweniToPbjBytes(EVM_ADDRESS))) - .willReturn(ResponseCodeEnum.MAX_CHILD_RECORDS_EXCEEDED); - final var reasonLazyCreationFailed = subject.tryLazyCreation(EVM_ADDRESS); - - assertTrue(reasonLazyCreationFailed.isPresent()); - assertEquals(CustomExceptionalHaltReason.TOO_MANY_CHILD_RECORDS, reasonLazyCreationFailed.get()); - } - - @Test - void noHaltIfLazyCreationOk() { - given(dispatch.createHollowAccount(tuweniToPbjBytes(EVM_ADDRESS))).willReturn(ResponseCodeEnum.OK); - final var reasonLazyCreationFailed = subject.tryLazyCreation(EVM_ADDRESS); - - assertTrue(reasonLazyCreationFailed.isEmpty()); - } - - @Test - void translatesMaxAccountsCreated() { - given(dispatch.createHollowAccount(tuweniToPbjBytes(EVM_ADDRESS))) - .willReturn(ResponseCodeEnum.MAX_ENTITIES_IN_PRICE_REGIME_HAVE_BEEN_CREATED); - final var reasonLazyCreationFailed = subject.tryLazyCreation(EVM_ADDRESS); - - assertTrue(reasonLazyCreationFailed.isPresent()); - assertEquals(CustomExceptionalHaltReason.ACCOUNTS_LIMIT_REACHED, reasonLazyCreationFailed.get()); - } - - @Test - void throwsOnUnexpectedFailureMode() { - given(dispatch.createHollowAccount(tuweniToPbjBytes(EVM_ADDRESS))) - .willReturn(ResponseCodeEnum.INVALID_ALIAS_KEY); - assertThrows(IllegalStateException.class, () -> subject.tryLazyCreation(EVM_ADDRESS)); - } - - @Test - void throwsOnLazyCreateOfLongZeroAddress() { - assertThrows(IllegalArgumentException.class, () -> subject.tryLazyCreation(LONG_ZERO_ADDRESS)); - } - - @Test - void throwsOnLazyCreateOfNonExpiredAccount() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM)); - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - - assertThrows(IllegalArgumentException.class, () -> subject.tryLazyCreation(EVM_ADDRESS)); - } - - @Test - void transferDelegationUsesExpectedVerifierForNonDelegate() { - final var captor = ArgumentCaptor.forClass(VerificationStrategy.class); - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - given(dispatch.transferWithReceiverSigCheck(eq(123L), eq(ACCOUNT_NUM), eq(BENEFICIARY_NUM), captor.capture())) - .willReturn(OK); - final var reasonToHaltDeletion = - subject.tryTransferFromContract(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS, 123L, false); - assertTrue(reasonToHaltDeletion.isEmpty()); - final var strategy = assertInstanceOf(ActiveContractVerificationStrategy.class, captor.getValue()); - assertEquals(ACCOUNT_NUM, strategy.getActiveNumber()); - assertEquals(tuweniToPbjBytes(LONG_ZERO_ADDRESS), strategy.getActiveAddress()); - assertFalse(strategy.requiresDelegatePermission()); - } - - @Test - void transferDelegationReportsInvalidSignature() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - given(dispatch.transferWithReceiverSigCheck(eq(123L), eq(ACCOUNT_NUM), eq(BENEFICIARY_NUM), any())) - .willReturn(INVALID_SIGNATURE); - final var reasonToHaltDeletion = - subject.tryTransferFromContract(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS, 123L, false); - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(INVALID_RECEIVER_SIGNATURE, reasonToHaltDeletion.get()); - } - - @Test - void transferDelegationThrowsOnApparentlyImpossibleFailureMode() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).smartContract(true)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - given(dispatch.transferWithReceiverSigCheck(eq(123L), eq(ACCOUNT_NUM), eq(BENEFICIARY_NUM), any())) - .willReturn(INSUFFICIENT_ACCOUNT_BALANCE); - assertThrows( - IllegalStateException.class, - () -> subject.tryTransferFromContract(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS, 123L, false)); - } - - @Test - void deletedAccountCannotBeTokenTreasury() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).numberTreasuryTitles(1)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(TOKEN_TREASURY_SELFDESTRUCT, reasonToHaltDeletion.get()); - } - - @Test - void deletedAccountCannotHaveTokenBalances() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM).numberPositiveBalances(1)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(TOKEN_HOLDER_SELFDESTRUCT, reasonToHaltDeletion.get()); - } - - @Test - void deletionsAreTracked() { - givenWellKnownAccount(accountWith(ACCOUNT_NUM)); - givenWellKnownAccount(BENEFICIARY_NUM, accountWith(BENEFICIARY_NUM)); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(LONG_ZERO_ADDRESS, BENEFICIARY_ADDRESS); - - assertTrue(reasonToHaltDeletion.isEmpty()); - verify(dispatch).trackDeletion(ACCOUNT_NUM, BENEFICIARY_NUM); - } - - @Test - void beneficiaryCannotBeSelf() { - final var reasonToHaltDeletion = subject.tryTrackingDeletion(EVM_ADDRESS, EVM_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(SELFDESTRUCT_TO_SELF, reasonToHaltDeletion.get()); - } - - @Test - void tokenAccountsCannotBeBeneficiaries() { - givenWellKnownToken(); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(EVM_ADDRESS, TOKEN_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(MISSING_ADDRESS, reasonToHaltDeletion.get()); - } - - @Test - void senderAccountMustBeC() { - givenWellKnownToken(); - - final var reasonToHaltDeletion = subject.tryTrackingDeletion(EVM_ADDRESS, TOKEN_ADDRESS); - - assertTrue(reasonToHaltDeletion.isPresent()); - assertEquals(MISSING_ADDRESS, reasonToHaltDeletion.get()); - } - @Test void returnsProxyAccountForNormal() { givenWellKnownAccount(accountWith(ACCOUNT_NUM)); @@ -580,24 +295,6 @@ void returnsNullForMissingAlias() { assertNull(subject.getAccount(EVM_ADDRESS)); } - @Test - void missingAliasIsNotHollow() { - assertFalse(subject.isHollowAccount(EVM_ADDRESS)); - } - - @Test - void missingAccountIsNotHollow() { - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - assertFalse(subject.isHollowAccount(EVM_ADDRESS)); - } - - @Test - void extantAccountIsHollowOnlyIfHasAnEmptyKey() { - given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); - givenWellKnownAccount(accountWith(ACCOUNT_NUM).key(Key.newBuilder().keyList(KeyList.DEFAULT))); - assertTrue(subject.isHollowAccount(EVM_ADDRESS)); - } - @Test void usesResolvedNumberFromDispatch() { given(dispatch.resolveAlias(Bytes.wrap(EVM_ADDRESS.toArrayUnsafe()))).willReturn(new EntityNumber(ACCOUNT_NUM)); @@ -643,11 +340,7 @@ private void givenWellKnownBytecode() { } private void givenWellKnownAccount(final Account.Builder builder) { - givenWellKnownAccount(ACCOUNT_NUM, builder); - } - - private void givenWellKnownAccount(final long number, final Account.Builder builder) { - given(dispatch.getAccount(number)).willReturn(builder.build()); + given(dispatch.getAccount(ACCOUNT_NUM)).willReturn(builder.build()); } private void givenWellKnownToken() { diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/EvmFrameStateTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/EvmFrameStateTest.java index e2ff763d3178..5d107ea4b678 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/EvmFrameStateTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/EvmFrameStateTest.java @@ -23,7 +23,7 @@ import com.hedera.hapi.node.state.contract.Bytecode; import com.hedera.hapi.node.state.contract.SlotKey; import com.hedera.hapi.node.state.contract.SlotValue; -import com.hedera.node.app.service.contract.impl.state.ContractSchema; +import com.hedera.node.app.service.contract.impl.ContractServiceImpl; import com.hedera.node.app.service.contract.impl.state.DispatchingEvmFrameState; import com.hedera.node.app.service.contract.impl.state.EvmFrameState; import com.hedera.node.app.spi.meta.bni.Dispatch; @@ -54,9 +54,9 @@ class EvmFrameStateTest { @Test void constructsDispatchingEvmFrameStateFromScope() { - given(writableStates.get(ContractSchema.STORAGE_KEY)) + given(writableStates.get(ContractServiceImpl.STORAGE_KEY)) .willReturn(storage); - given(writableStates.get(ContractSchema.BYTECODE_KEY)) + given(writableStates.get(ContractServiceImpl.BYTECODE_KEY)) .willReturn(bytecode); given(scope.writableContractState()).willReturn(writableStates); given(scope.dispatch()).willReturn(dispatch); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyEvmAccountTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyEvmAccountTest.java index 6a7ba6749fde..9bc0e12f11ea 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyEvmAccountTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyEvmAccountTest.java @@ -57,11 +57,6 @@ void setUp() { subject = new ProxyEvmAccount(ACCOUNT_NUM, hederaState); } - @Test - void notTokenFacade() { - assertFalse(subject.isTokenFacade()); - } - @Test void accountHashNotSupported() { assertThrows(UnsupportedOperationException.class, subject::getAddressHash); @@ -145,12 +140,6 @@ void doesNotSupportDirectBalanceMutation() { assertThrows(UnsupportedOperationException.class, () -> subject.setBalance(Wei.of(123))); } - @Test - void delegatesCheckingContract() { - given(hederaState.isContract(ACCOUNT_NUM)).willReturn(true); - assertTrue(subject.isContract()); - } - @Test void isItselfMutable() { assertSame(subject, subject.getMutable()); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyWorldUpdaterTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyWorldUpdaterTest.java index b67d5a9756ed..ee90d8f70486 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyWorldUpdaterTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/ProxyWorldUpdaterTest.java @@ -16,26 +16,20 @@ package com.hedera.node.app.service.contract.impl.test.state; -import static com.hedera.node.app.service.contract.impl.exec.failure.CustomExceptionalHaltReason.INVALID_RECEIVER_SIGNATURE; -import static com.hedera.node.app.service.contract.impl.test.TestHelpers.EIP_1014_ADDRESS; -import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.*; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.aliasFrom; +import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.asLongZeroAddress; import static org.hyperledger.besu.datatypes.Address.ALTBN128_ADD; import static org.hyperledger.besu.datatypes.Address.ZERO; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; -import com.hedera.hapi.node.base.AccountID; -import com.hedera.hapi.node.base.ContractID; import com.hedera.node.app.service.contract.impl.state.EvmFrameState; import com.hedera.node.app.service.contract.impl.state.EvmFrameStateFactory; -import com.hedera.node.app.service.contract.impl.state.ProxyEvmAccount; import com.hedera.node.app.service.contract.impl.state.ProxyWorldUpdater; import com.hedera.node.app.spi.meta.bni.Dispatch; import com.hedera.node.app.spi.meta.bni.Scope; import java.util.List; -import java.util.Optional; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.evm.account.Account; @@ -66,9 +60,6 @@ class ProxyWorldUpdaterTest { @Mock private EvmAccount mutableAccount; - @Mock - private ProxyEvmAccount proxyEvmAccount; - @Mock private Scope scope; @@ -100,73 +91,6 @@ void getsImmutableAccount() { assertSame(anImmutableAccount, subject.get(ALTBN128_ADD)); } - @Test - void getsHederaAccountByNumber() { - final var num = ALTBN128_ADD.toBigInteger().longValueExact(); - final var numericId = AccountID.newBuilder().accountNum(num).build(); - given(evmFrameState.getAddress(num)).willReturn(ALTBN128_ADD); - given(evmFrameState.getAccount(ALTBN128_ADD)).willReturn(proxyEvmAccount); - assertSame(proxyEvmAccount, subject.getHederaAccount(numericId)); - } - - @Test - void getsHederaContractByNumber() { - final var num = ALTBN128_ADD.toBigInteger().longValueExact(); - final var numericId = ContractID.newBuilder().contractNum(num).build(); - given(evmFrameState.getAddress(num)).willReturn(ALTBN128_ADD); - given(evmFrameState.getAccount(ALTBN128_ADD)).willReturn(proxyEvmAccount); - assertSame(proxyEvmAccount, subject.getHederaAccount(numericId)); - } - - @Test - void returnsNullHederaAccountIfMissing() { - final var num = ALTBN128_ADD.toBigInteger().longValueExact(); - final var numericId = AccountID.newBuilder().accountNum(num).build(); - doThrow(IllegalArgumentException.class).when(evmFrameState).getAddress(num); - assertNull(subject.getHederaAccount(numericId)); - } - - @Test - void returnsNullHederaContractIfMissing() { - final var num = ALTBN128_ADD.toBigInteger().longValueExact(); - final var numericId = ContractID.newBuilder().contractNum(num).build(); - doThrow(IllegalArgumentException.class).when(evmFrameState).getAddress(num); - assertNull(subject.getHederaAccount(numericId)); - } - - @Test - void getsHederaAccountByAlias() { - final var aliasId = AccountID.newBuilder() - .alias(tuweniToPbjBytes( - asLongZeroAddress(ALTBN128_ADD.toBigInteger().longValueExact()))) - .build(); - given(evmFrameState.getAccount(ALTBN128_ADD)).willReturn(proxyEvmAccount); - assertSame(proxyEvmAccount, subject.getHederaAccount(aliasId)); - } - - @Test - void getsHederaContractByAlias() { - final var aliasId = ContractID.newBuilder() - .evmAddress(tuweniToPbjBytes( - asLongZeroAddress(ALTBN128_ADD.toBigInteger().longValueExact()))) - .build(); - given(evmFrameState.getAccount(ALTBN128_ADD)).willReturn(proxyEvmAccount); - assertSame(proxyEvmAccount, subject.getHederaAccount(aliasId)); - } - - @Test - void delegatesHollowCheck() { - given(evmFrameState.isHollowAccount(ALTBN128_ADD)).willReturn(true); - - assertTrue(subject.isHollowAccount(ALTBN128_ADD)); - } - - @Test - void delegatesHollowFinalization() { - subject.finalizeHollowAccount(EIP_1014_ADDRESS); - verify(evmFrameState).finalizeHollowAccount(EIP_1014_ADDRESS); - } - @Test void getsMutableAccount() { given(evmFrameState.getMutableAccount(ALTBN128_ADD)).willReturn(mutableAccount); @@ -291,15 +215,6 @@ void updaterHasExpectedProperties() { assertSame(subject, updater.parentUpdater().get()); } - @Test - void delegatesTransfer() { - given(evmFrameState.tryTransferFromContract(ALTBN128_ADD, SOME_EVM_ADDRESS, 123L, true)) - .willReturn(Optional.of(INVALID_RECEIVER_SIGNATURE)); - final var maybeHaltReason = subject.tryTransferFromContract(ALTBN128_ADD, SOME_EVM_ADDRESS, 123L, true); - assertTrue(maybeHaltReason.isPresent()); - assertEquals(INVALID_RECEIVER_SIGNATURE, maybeHaltReason.get()); - } - @Test void onlyReturnsNonDeletedAccountsAsTouched() { givenDispatch(); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/TokenEvmAccountTest.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/TokenEvmAccountTest.java index 38b7910ff1ec..35653d649208 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/TokenEvmAccountTest.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/com/hedera/node/app/service/contract/impl/test/state/TokenEvmAccountTest.java @@ -17,7 +17,10 @@ package com.hedera.node.app.service.contract.impl.test.state; import static com.hedera.node.app.service.contract.impl.utils.ConversionUtils.pbjToTuweniBytes; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.BDDMockito.given; import com.hedera.node.app.service.contract.impl.state.EvmFrameState; @@ -51,11 +54,6 @@ void setUp() { subject = new TokenEvmAccount(TOKEN_ADDRESS, state); } - @Test - void tokenFacade() { - assertTrue(subject.isTokenFacade()); - } - @Test void usesGivenAddress() { assertSame(TOKEN_ADDRESS, subject.getAddress()); diff --git a/hedera-node/hedera-smart-contract-service-impl/src/test/java/module-info.java b/hedera-node/hedera-smart-contract-service-impl/src/test/java/module-info.java index f5f641ce0bdb..d3017d142b74 100644 --- a/hedera-node/hedera-smart-contract-service-impl/src/test/java/module-info.java +++ b/hedera-node/hedera-smart-contract-service-impl/src/test/java/module-info.java @@ -8,16 +8,8 @@ requires org.assertj.core; requires org.junit.jupiter.api; requires org.mockito.junit.jupiter; - requires com.hedera.node.app.spi; - requires com.hedera.pbj.runtime; - requires org.hyperledger.besu.evm; - requires org.hyperledger.besu.datatypes; - requires com.github.spotbugs.annotations; - requires tuweni.bytes; - requires tuweni.units; - requires com.hedera.node.config; requires org.mockito; - requires com.hedera.node.config.test.fixtures; + requires tuweni.units; opens com.hedera.node.app.service.contract.impl.test to org.junit.platform.commons; @@ -27,20 +19,4 @@ org.junit.platform.commons; opens com.hedera.node.app.service.contract.impl.test.handlers to org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.operations to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.gas to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.v030 to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.v034 to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.v038 to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.exec.processors to - org.junit.platform.commons; - opens com.hedera.node.app.service.contract.impl.test.hevm to - org.junit.platform.commons; }